@longzai-intelligence-issues/ledger 0.0.2 → 0.0.3

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/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import"./rolldown-runtime-BqT_7tdF.js";import{renderBaselineRegeneratedConfig as e}from"@longzai-intelligence-issues/config";import{existsSync as t,mkdirSync as n,readFileSync as r,readdirSync as i,renameSync as a,rmSync as o,statSync as s,writeFileSync as c}from"node:fs";import{dirname as l,join as u,posix as d,resolve as f}from"node:path";import{execFileSync as p}from"node:child_process";import{createHash as m}from"node:crypto";const h=/^[0-9]{3,4}-.+\.md$/,g=/^[a-z0-9]+(?:-[a-z0-9]+)*$/,_=`状态\\*{0,2}\\s*[::]`,v=RegExp(_),y=30,b=/[((]([^))]{4,})[))]/,ee=`处置结果`,x=/(?:处置中|待回填)(?=[))::,,。;;、]|——|$)/,te=8,ne=[`证据锚点(末次通过零执行收口`,`判据执行证据(`],re=/^```criteria\s*$/,ie=/^```\s*$/,S=/^[A-Za-z0-9][A-Za-z0-9._-]*$/,C=`沿革`,w=`阻塞`,ae=`\\*{0,2}%s\\*{0,2}\\s*[::]`,T={red:`🔴 待处理`,yellow:`🟡 处理中`,green:`🟢 已处置`,frozen:`⚪ 已冻结`,canceled:`⚫ 已取消`},oe={green:[`已解决`,`已修复`,`已治理`,`已处理`,`已处置`,`已完成`,`已闭合`,`已消解`,`已闭环`,`已清治`,`已收口`,`已根治`,`已终态`,`已裁决`,`已决策`,`已验证`,`已全部清治`,`全量完成`,`终态达成`],red:[`未处理`,`待处理`,`待治理`,`待修复`,`未修复`,`待验证`,`待评估`,`紧急`,`已立项待治理`],deferred:[`已登记`],canceled:[`已取消`],inProgress:[`处理中`,`进行中`],frozen:[`已冻结`]},se=/\[([0-9]{3,4})(?:-([a-z0-9-]+))?\](?:\(([^)]*)\))?/g,ce=/([0-9]{3,4})-([a-z0-9-]+)\.md/;function le(e){let t=[],n=new RegExp(se.source,`g`),r=n.exec(e);for(;r!==null;){let i=r[1]??``,a=r[2]??null,o=r[3]??null;a===null&&o!==null&&(a=ce.exec(o)?.[2]??null),t.some(e=>e.number===i&&e.slug===a)||t.push({number:i,slug:a}),r=n.exec(e)}return t}function ue(e){return RegExp(`^\\*{0,2}${e}\\*{0,2}\\s*[::]`)}function E(e){return e.includes(`已冻结`)?`frozen`:e.includes(`🔴`)?`red`:e.includes(`⚫`)?`canceled`:/🟡\s*处理中/.test(e)?`yellow`:e.includes(`🟡`)?`legacy-yellow`:/🟢\s*已处置/.test(e)?`green`:e.includes(`🟢`)||e.includes(`✅`)?`legacy-green`:`unknown`}const de=/证书指纹\s+([0-9a-f]{64})/,fe=/退出码\s*0(?!\d)|EXIT\s*=\s*0(?!\d)/i,pe=/(?<![未待])全(?:绿|过|部通过)/,me=/用户[^。\n]{0,30}自验/;function he(e){let t=e.split(/\r?\n/),n=t.findIndex(e=>e.startsWith(`## `)&&e.includes(`处置结果`));if(n===-1)return``;let r=t.length;for(let e=n+1;e<t.length;e+=1)if((t[e]??``).startsWith(`## `)){r=e;break}return t.slice(n,r).join(`
2
- `)}function ge(e){let t=[],n=new Set,r=0;for(let i of e.split(/\r?\n/)){if(i.trim().startsWith("```")){r=+(r===0);continue}if(r>0)continue;let e=[{kind:`certificate`,pattern:de},{kind:`exit-zero`,pattern:fe},{kind:`all-green`,pattern:pe},{kind:`adjudicated`,pattern:me}];for(let r of e)!n.has(r.kind)&&r.pattern.test(i)&&(t.push({kind:r.kind,line:i}),n.add(r.kind))}return t}function _e(e){let t=he(e);return{anchors:ge(t),dispositionText:t}}function ve(e,t){return t.find(t=>e.includes(t))??null}function ye(e){let t=b.exec(e);return t===null?null:(t[1]??``).trim()}var D=class extends Error{constructor(e,t){super(`glob 模式「${e}」非法:${t}`),this.name=`MiniGlobError`}};const be=new Set([`.`,`^`,`$`,`+`,`(`,`)`,`|`,`\\`,`]`]),xe=new Map;function Se(e){return be.has(e)?`\\${e}`:e}function Ce(e,t){let n=``,r=0;for(;r<t.length;){let i=t[r]??``;if(i===`[`)throw new D(e,`不支持字符类 [(与既有生态对齐,显式抛错不静默误配)`);if(i===`*`){let e=0;for(;(t[r+e]??``)===`*`;)e+=1;if(e>=2&&(t[r+e]??``)===`/`){n+=`(?:.*/)?`,r+=e+1;continue}if(e>=2){n+=`[\\s\\S]*`,r+=e;continue}n+=`[^/]*`,r+=1;continue}if(i===`?`){n+=`[^/]`,r+=1;continue}n+=Se(i),r+=1}return n}function we(e,t){let n=t.indexOf(`{`);if(n===-1)return Ce(e,t);let r=t.indexOf(`}`,n+1);if(r===-1)throw new D(e,`大括号未闭合`);let i=t.slice(0,n),a=t.slice(n+1,r);if(a.includes(`{`))throw new D(e,`不支持嵌套大括号`);let o=a.split(`,`),s=t.slice(r+1);return`(?:${o.map(t=>we(e,`${i}${t}${s}`)).join(`|`)})`}function Te(e){let t=xe.get(e);if(t!==void 0)return t;let n=RegExp(`^${we(e,e)}$`);return xe.set(e,n),n}function O(e,t){return Te(e).test(t)}const Ee=new Set([`*`,`?`,`{`,`}`]);function k(e){return[...e].some(e=>Ee.has(e))}function De(e){let t=[];for(let n of e){let e=n.split(`/`).filter(e=>e!==``).slice(0,-1),r=[``];for(let t of e){let e=/^\{([^{}]+)\}$/.exec(t);if(e!==null){let t=[];for(let n of(e[1]??``).split(`,`))k(n)?t.push(...r):t.push(...r.map(e=>Oe(e,n)));r=t;continue}if(k(t))break;r=r.map(e=>Oe(e,t))}t.push(...r)}let n=[...new Set(t)];return n.filter(e=>e===``||!n.some(t=>t!==e&&(t===``||e.startsWith(`${t}/`))))}function Oe(e,t){return e===``?t:`${e}/${t}`}function ke(e,t){return e.some(e=>O(e,t)||O(e,`${t}/`)||O(e,`${t}/**`))}function Ae(e,t){return e.some(e=>O(e,t))}function je(e,t){return e.some(e=>e===``||t===e||t.startsWith(`${e}/`)||e.startsWith(`${t}/`))}function Me(e,t){return e.some(e=>e===``||t.startsWith(`${e}/`))}function A(e,n,r,a,o,s){if(!t(e)){if(o)throw Error(`扫描面目录缺失:${e}(严格模式防扫描面静默缩水)`);return}let c=i(e,{withFileTypes:!0}).sort((e,t)=>e.name.localeCompare(t.name));for(let t of c){let i=n===``?t.name:`${n}/${t.name}`;if(t.isDirectory()){if(t.name===`.git`||ke(a,i)||!je(r,i))continue;A(u(e,t.name),i,r,a,o,s);continue}if(t.isFile()){if(Ae(a,i)||!Me(r,i))continue;s.push(d.normalize(i))}}}function j(e,t,n={}){let r=[];return A(e,``,t,n.excludeGlobs??[],!1,r),r.sort((e,t)=>e.localeCompare(t))}function M(e,t={}){let n=[];return A(e,``,[``],t.excludeGlobs??[],!0,n),n.sort((e,t)=>e.localeCompare(t))}function N(e){let t=/^([0-9]{3,4})-(.+)\.md$/.exec(e);return t===null?null:{id:t[1]??``,slug:t[2]??``}}function Ne(e){let t=[],n=-1;return e.forEach((e,r)=>{if(n===-1){re.test(e)&&(n=r);return}ie.test(e)&&(t.push({start:n,end:r}),n=-1)}),n!==-1&&t.push({start:n,end:-1}),t}function Pe(e){let t=e.split(/\r?\n/),n=Ne(t);if(n.length===0)throw Error("未找到 criteria 围栏块(```criteria 开栏)");if(n.length>1){let e=(n[1]?.start??0)+1;throw Error(`criteria 围栏块必须唯一:第 ${e} 行出现第二块`)}let r=n[0];if(r===void 0)throw Error("未找到 criteria 围栏块(```criteria 开栏)");if(r.end===-1)throw Error(`criteria 围栏块未闭合(第 ${r.start+1} 行开栏后无闭栏)`);let i=null,a=0,o=[];for(let e=r.start+1;e<r.end;e+=1){let n=t[e]??``,r=e+1;if(n.trim()===``||n.trimStart().startsWith(`#`))continue;if(n.startsWith(`summary:`)){let e=n.slice(8).trim();if(e===``)throw Error(`第 ${r} 行 summary 值为空(须唯一且非空)`);if(a+=1,a>1)throw Error(`第 ${r} 行 summary 重复(summary 行必须唯一)`);i=e;continue}let s=n.split(`|`);if(s.length!==4)throw Error(`第 ${r} 行判据须为四段 label|channel|cwd|command(命令含竖线须以脚本承载)`);let c=(s[0]??``).trim(),l=(s[1]??``).trim(),u=(s[2]??``).trim(),d=(s[3]??``).trim();if(c===``||l===``||u===``||d===``)throw Error(`第 ${r} 行判据存在空段(四段逐段非空)`);if(!S.test(l))throw Error(`第 ${r} 行 channel「${l}」不合法(限字母数字起首的 [A-Za-z0-9._-])`);o.push({label:c,channel:l,cwd:u,command:d})}if(o.length===0)throw Error(`criteria 围栏块内至少一条判据(第 ${r.start+1} 行块为空)`);return{summary:i,criteria:o}}function Fe(e,t){let n=ue(t),r=Math.min(e.length,30);for(let t=0;t<r;t+=1){let r=e[t]??``;if(n.test(r))return le(r)}return[]}function P(e,t,n){let r=N(e);if(r===null)return null;let i=t.split(/\r?\n/),a=``;for(let e of i)if(e.startsWith(`# `)){a=e.slice(2).trim();break}let o=``,s=0,c=`unknown`,l=Math.min(i.length,30);for(let e=0;e<l;e+=1){let t=i[e]??``;if(v.test(t)){o=t.trim(),s=e+1,c=E(t);break}}let u=o===``?null:b.exec(o),d=u===null?null:(u[1]??``).trim(),f=-1;i.forEach((e,t)=>{f===-1&&e.startsWith(`## `)&&e.includes(`处置结果`)&&(f=t)});let p=!1;if(f!==-1){let e=Math.min(i.length,f+8);for(let t=f;t<e;t+=1)if(x.test(i[t]??``)){p=!0;break}}let m=ne.some(e=>t.includes(e)),h=null,g=null;if(Ne(i).length>0)try{h=Pe(t)}catch(e){g=e instanceof Error?e.message:String(e)}return{id:r.id,slug:r.slug,file:e,title:a,status:c,statusLine:o,statusLineNumber:s,pendingReason:d,hasDispositionSection:f!==-1,dispositionIsPlaceholder:p,hasEvidenceAnchorBlock:m,criteria:h,criteriaError:g,historyRefs:Fe(i,C),blockedByRefs:Fe(i,w),rawContent:t,modifiedAtMs:n}}function F(e){if(!t(e))return[];let n=i(e).filter(e=>h.test(e)).sort((e,t)=>e.localeCompare(t)),a=[];for(let t of n){let n=u(e,t);try{let e=r(n,`utf8`),i=s(n).mtimeMs,o=P(t,e,i);o!==null&&a.push(o)}catch{a.push({id:N(t)?.id??``,slug:N(t)?.slug??``,file:t,title:``,status:`unknown`,statusLine:``,statusLineNumber:0,pendingReason:null,hasDispositionSection:!1,dispositionIsPlaceholder:!1,hasEvidenceAnchorBlock:!1,criteria:null,criteriaError:null,historyRefs:[],blockedByRefs:[],rawContent:``,modifiedAtMs:0})}}return a}const Ie=/\[([0-9]{3,4})(?:-([a-z0-9-]+))?\]/g;function Le(e,t){return t.scopes.flatMap(t=>F(u(e,t.registryDir)).map(e=>({scopeKey:t.key,number:e.id,slug:e.slug})))}function Re(e,t,n){let r=n.filter(t=>t.number===e);if(r.length===0)return{kind:`unknown`,message:`引用编号 ${e} 在全部 scope 中无命中`};if((t===null?[]:r.filter(e=>e.slug===t)).length===1)return{kind:`ok`};let i=t===null?r:r.filter(e=>e.slug.startsWith(t));return i.length===1?{kind:`ok`}:i.length===0?{kind:`unknown`,message:`引用 ${e}-${t} 在 scope 候选集中无 slug 命中(编号命中:${r.map(e=>`${e.scopeKey}/${e.number}-${e.slug}`).join(`、`)})`}:{kind:`ambiguous`,message:`引用 ${e}${t===null?``:`-${t}`} 命中不唯一——候选:${i.map(e=>`${e.scopeKey}/${e.number}-${e.slug}`).join(`、`)}(请展开完整 slug 或注明 scope)`}}function ze(e){if(e.config.docs===void 0)throw Error(`配置未登记 docs 节(docs.scanRoots)——docs 引用检查显式拒绝隐式扫描面`);let t=Le(e.root,e.config),n=[],i=0;for(let a of e.config.docs.scanRoots){let o=M(u(e.root,a),{excludeGlobs:e.config.docs.exclusions.map(e=>e.glob)});i+=o.length;for(let i of o){if(!e.config.docs.includeExtensions.some(e=>i.endsWith(e)))continue;let o=r(u(e.root,a,i),`utf8`),s=He(o),c=a===``?i:`${a}/${i}`,l=new RegExp(Ie.source,`g`),d=l.exec(o);for(;d!==null;){let e=Re(d[1]??``,d[2]??null,t);if(e.kind!==`ok`){let t=Ue(s,d.index??0);n.push({file:c,line:t.line,column:t.column,rule:e.kind===`unknown`?`doc-ref-unknown`:`doc-ref-ambiguous`,message:e.message})}d=l.exec(o)}}}let a=new Map((e.config.docs.baseline??[]).map(e=>[`${e.file}::${e.rule}`,e]));if(e.ignoreBaseline===!0)return{violations:n,suppressed:0,scannedFiles:i};let o=[],s=0,c=new Set;for(let e of n){let t=`${e.file}::${e.rule}`;if(a.has(t)){s+=1,c.add(t);continue}o.push(e)}let l=[...a.entries()].filter(([e])=>!c.has(e)).map(([e,t])=>({file:e.split(`::`)[0]??``,line:0,column:0,rule:`baseline-stale`,message:`docs 基线条目已无对应现行违规——棘轮只许缩短,须同步删除该条目(收编指针:${t.issue})`}));return{violations:[...o,...l].sort((e,t)=>e.file.localeCompare(t.file)||e.rule.localeCompare(t.rule)),suppressed:s,scannedFiles:i}}function Be(e){if(e.config.docs===void 0)throw Error(`配置未登记 docs 节(docs.scanRoots)——docs 修复显式拒绝隐式扫描面`);let t=Le(e.root,e.config),n=[],i=[];for(let a of e.config.docs.scanRoots){let o=M(u(e.root,a),{excludeGlobs:e.config.docs.exclusions.map(e=>e.glob)});for(let s of o){if(!e.config.docs.includeExtensions.some(e=>s.endsWith(e)))continue;let o=r(u(e.root,a,s),`utf8`),l=[],d=new RegExp(Ie.source,`g`),f=d.exec(o);for(;f!==null;){let e=f[1]??``,n=f[2]??null;if(n!==null){let r=t.filter(t=>t.number===e&&t.slug.startsWith(n));if(r.length>1){let t=Ue(He(o),f.index??0);i.push({file:s,line:t.line,column:t.column,rule:`refused`,message:`引用 ${e}-${n} 前缀命中不唯一,无法机械归位(候选:${r.map(e=>`${e.scopeKey}/${e.number}-${e.slug}`).join(`、`)})——需人工核定`})}else r.length===1&&r[0]?.slug!==n&&l.push({start:f.index??0,end:(f.index??0)+f[0].length,replacement:`[${e}-${r[0]?.slug}]`})}f=d.exec(o)}if(l.length===0)continue;let p=o;for(let e of[...l].sort((e,t)=>t.start-e.start))p=`${p.slice(0,e.start)}${e.replacement}${p.slice(e.end)}`;e.dryRun!==!0&&p!==o?(c(u(e.root,a,s),p),n.push(s)):e.dryRun===!0&&n.push(s)}}return{fixedFiles:n,refused:i}}function Ve(t){if(t.config.docs===void 0)throw Error(`配置未登记 docs 节——无法再生 docs 基线`);if(t.issuePointer.trim()===``)return{ok:!1,error:`再生须携带非空 --issue <指针>(收编盖章)`};let n=ze({root:t.root,config:t.config,ignoreBaseline:!0}).violations,r=new Set((t.config.docs.baseline??[]).map(e=>`${e.file}::${e.rule}`)),i=n.filter(e=>!r.has(`${e.file}::${e.rule}`));if(i.length>0)return{ok:!1,error:`存在 ${i.length} 项基线外新增违规,拒绝再生(先处置新增违规后再收编存量):\n${i.slice(0,10).map(e=>`${e.file}:${e.line} [${e.rule}]`).join(`
1
+ import"./rolldown-runtime-BqT_7tdF.js";import{renderBaselineRegeneratedConfig as e}from"@longzai-intelligence-issues/config";import{existsSync as t,mkdirSync as n,readFileSync as r,readdirSync as i,renameSync as a,rmSync as o,statSync as s,writeFileSync as c}from"node:fs";import{dirname as l,join as u,posix as d,resolve as f}from"node:path";import{execFileSync as p}from"node:child_process";import{createHash as m}from"node:crypto";const h=/^[0-9]{3,4}-.+\.md$/,g=/^[a-z0-9]+(?:-[a-z0-9]+)*$/,_=`状态\\*{0,2}\\s*[::]`,v=RegExp(_),ee=30,y=/[((]([^))]{4,})[))]/,b=`处置结果`,x=/(?:处置中|待回填)(?=[))::,,。;;、]|——|$)/,te=8,S=[`证据锚点(末次通过零执行收口`,`判据执行证据(`],C=/^```criteria\s*$/,ne=/^```\s*$/,re=/^[A-Za-z0-9][A-Za-z0-9._-]*$/,w=`沿革`,T=`阻塞`,ie=`\\*{0,2}%s\\*{0,2}\\s*[::]`,E={red:`🔴 待处理`,yellow:`🟡 处理中`,green:`🟢 已处置`,frozen:`⚪ 已冻结`,canceled:`⚫ 已取消`},ae={green:[`已解决`,`已修复`,`已治理`,`已处理`,`已处置`,`已完成`,`已闭合`,`已消解`,`已闭环`,`已清治`,`已收口`,`已根治`,`已终态`,`已裁决`,`已决策`,`已验证`,`已全部清治`,`全量完成`,`终态达成`],red:[`未处理`,`待处理`,`待治理`,`待修复`,`未修复`,`待验证`,`待评估`,`紧急`,`已立项待治理`],deferred:[`已登记`],canceled:[`已取消`],inProgress:[`处理中`,`进行中`],frozen:[`已冻结`]},oe=/\[([0-9]{3,4})(?:-([a-z0-9-]+))?\](?:\(([^)]*)\))?/g,se=/([0-9]{3,4})-([a-z0-9-]+)\.md/;function ce(e){let t=[],n=new RegExp(oe.source,`g`),r=n.exec(e);for(;r!==null;){let i=r[1]??``,a=r[2]??null,o=r[3]??null;a===null&&o!==null&&(a=se.exec(o)?.[2]??null),t.some(e=>e.number===i&&e.slug===a)||t.push({number:i,slug:a}),r=n.exec(e)}return t}function le(e){return RegExp(`^\\*{0,2}${e}\\*{0,2}\\s*[::]`)}function D(e){return e.includes(`已冻结`)?`frozen`:e.includes(`🔴`)?`red`:e.includes(`⚫`)?`canceled`:/🟡\s*处理中/.test(e)?`yellow`:e.includes(`🟡`)?`legacy-yellow`:/🟢\s*已处置/.test(e)?`green`:e.includes(`🟢`)||e.includes(`✅`)?`legacy-green`:`unknown`}const ue=/证书指纹\s+([0-9a-f]{64})/,de=/退出码\s*0(?!\d)|EXIT\s*=\s*0(?!\d)/i,fe=/(?<![未待])全(?:绿|过|部通过)/,pe=/用户[^。\n]{0,30}自验/;function me(e){let t=e.split(/\r?\n/),n=t.findIndex(e=>e.startsWith(`## `)&&e.includes(`处置结果`));if(n===-1)return``;let r=t.length;for(let e=n+1;e<t.length;e+=1)if((t[e]??``).startsWith(`## `)){r=e;break}return t.slice(n,r).join(`
2
+ `)}function he(e){let t=[],n=new Set,r=0;for(let i of e.split(/\r?\n/)){if(i.trim().startsWith("```")){r=+(r===0);continue}if(r>0)continue;let e=[{kind:`certificate`,pattern:ue},{kind:`exit-zero`,pattern:de},{kind:`all-green`,pattern:fe},{kind:`adjudicated`,pattern:pe}];for(let r of e)!n.has(r.kind)&&r.pattern.test(i)&&(t.push({kind:r.kind,line:i}),n.add(r.kind))}return t}function ge(e){let t=me(e);return{anchors:he(t),dispositionText:t}}function _e(e,t){return t.find(t=>e.includes(t))??null}function ve(e){let t=y.exec(e);return t===null?null:(t[1]??``).trim()}var O=class extends Error{constructor(e,t){super(`glob 模式「${e}」非法:${t}`),this.name=`MiniGlobError`}};const ye=new Set([`.`,`^`,`$`,`+`,`(`,`)`,`|`,`\\`,`]`]),be=new Map;function xe(e){return ye.has(e)?`\\${e}`:e}function Se(e,t){let n=``,r=0;for(;r<t.length;){let i=t[r]??``;if(i===`[`)throw new O(e,`不支持字符类 [(与既有生态对齐,显式抛错不静默误配)`);if(i===`*`){let e=0;for(;(t[r+e]??``)===`*`;)e+=1;if(e>=2&&(t[r+e]??``)===`/`){n+=`(?:.*/)?`,r+=e+1;continue}if(e>=2){n+=`[\\s\\S]*`,r+=e;continue}n+=`[^/]*`,r+=1;continue}if(i===`?`){n+=`[^/]`,r+=1;continue}n+=xe(i),r+=1}return n}function Ce(e,t){let n=t.indexOf(`{`);if(n===-1)return Se(e,t);let r=t.indexOf(`}`,n+1);if(r===-1)throw new O(e,`大括号未闭合`);let i=t.slice(0,n),a=t.slice(n+1,r);if(a.includes(`{`))throw new O(e,`不支持嵌套大括号`);let o=a.split(`,`),s=t.slice(r+1);return`(?:${o.map(t=>Ce(e,`${i}${t}${s}`)).join(`|`)})`}function we(e){let t=be.get(e);if(t!==void 0)return t;let n=RegExp(`^${Ce(e,e)}$`);return be.set(e,n),n}function k(e,t){return we(e).test(t)}const Te=new Set([`*`,`?`,`{`,`}`]);function Ee(e){return[...e].some(e=>Te.has(e))}function De(e){let t=[];for(let n of e){let e=n.split(`/`).filter(e=>e!==``).slice(0,-1),r=[``];for(let t of e){let e=/^\{([^{}]+)\}$/.exec(t);if(e!==null){let t=[];for(let n of(e[1]??``).split(`,`))Ee(n)?t.push(...r):t.push(...r.map(e=>Oe(e,n)));r=t;continue}if(Ee(t))break;r=r.map(e=>Oe(e,t))}t.push(...r)}let n=[...new Set(t)];return n.filter(e=>e===``||!n.some(t=>t!==e&&(t===``||e.startsWith(`${t}/`))))}function Oe(e,t){return e===``?t:`${e}/${t}`}function ke(e,t){return e.some(e=>k(e,t)||k(e,`${t}/`)||k(e,`${t}/**`))}function Ae(e,t){return e.some(e=>k(e,t))}function je(e,t){return e.some(e=>e===``||t===e||t.startsWith(`${e}/`)||e.startsWith(`${t}/`))}function Me(e,t){return e.some(e=>e===``||t.startsWith(`${e}/`))}function A(e,n,r,a,o,s){if(!t(e)){if(o)throw Error(`扫描面目录缺失:${e}(严格模式防扫描面静默缩水)`);return}let c=i(e,{withFileTypes:!0}).sort((e,t)=>e.name.localeCompare(t.name));for(let t of c){let i=n===``?t.name:`${n}/${t.name}`;if(t.isDirectory()){if(t.name===`.git`||ke(a,i)||!je(r,i))continue;A(u(e,t.name),i,r,a,o,s);continue}if(t.isFile()){if(Ae(a,i)||!Me(r,i))continue;s.push(d.normalize(i))}}}function j(e,t,n={}){let r=[];return A(e,``,t,n.excludeGlobs??[],!1,r),r.sort((e,t)=>e.localeCompare(t))}function M(e,t={}){let n=[];return A(e,``,[``],t.excludeGlobs??[],!0,n),n.sort((e,t)=>e.localeCompare(t))}function N(e){let t=/^([0-9]{3,4})-(.+)\.md$/.exec(e);return t===null?null:{id:t[1]??``,slug:t[2]??``}}function Ne(e){let t=[],n=-1;return e.forEach((e,r)=>{if(n===-1){C.test(e)&&(n=r);return}ne.test(e)&&(t.push({start:n,end:r}),n=-1)}),n!==-1&&t.push({start:n,end:-1}),t}function Pe(e){let t=e.split(/\r?\n/),n=Ne(t);if(n.length===0)throw Error("未找到 criteria 围栏块(```criteria 开栏)");if(n.length>1){let e=(n[1]?.start??0)+1;throw Error(`criteria 围栏块必须唯一:第 ${e} 行出现第二块`)}let r=n[0];if(r===void 0)throw Error("未找到 criteria 围栏块(```criteria 开栏)");if(r.end===-1)throw Error(`criteria 围栏块未闭合(第 ${r.start+1} 行开栏后无闭栏)`);let i=null,a=0,o=[];for(let e=r.start+1;e<r.end;e+=1){let n=t[e]??``,r=e+1;if(n.trim()===``||n.trimStart().startsWith(`#`))continue;if(n.startsWith(`summary:`)){let e=n.slice(8).trim();if(e===``)throw Error(`第 ${r} 行 summary 值为空(须唯一且非空)`);if(a+=1,a>1)throw Error(`第 ${r} 行 summary 重复(summary 行必须唯一)`);i=e;continue}let s=n.split(`|`);if(s.length!==4)throw Error(`第 ${r} 行判据须为四段 label|channel|cwd|command(命令含竖线须以脚本承载)`);let c=(s[0]??``).trim(),l=(s[1]??``).trim(),u=(s[2]??``).trim(),d=(s[3]??``).trim();if(c===``||l===``||u===``||d===``)throw Error(`第 ${r} 行判据存在空段(四段逐段非空)`);if(!re.test(l))throw Error(`第 ${r} 行 channel「${l}」不合法(限字母数字起首的 [A-Za-z0-9._-])`);o.push({label:c,channel:l,cwd:u,command:d})}if(o.length===0)throw Error(`criteria 围栏块内至少一条判据(第 ${r.start+1} 行块为空)`);return{summary:i,criteria:o}}function Fe(e,t){let n=le(t),r=Math.min(e.length,30);for(let t=0;t<r;t+=1){let r=e[t]??``;if(n.test(r))return ce(r)}return[]}function P(e,t,n){let r=N(e);if(r===null)return null;let i=t.split(/\r?\n/),a=``;for(let e of i)if(e.startsWith(`# `)){a=e.slice(2).trim();break}let o=``,s=0,c=`unknown`,l=Math.min(i.length,30);for(let e=0;e<l;e+=1){let t=i[e]??``;if(!t.startsWith(`#`)&&v.test(t)){o=t.trim(),s=e+1,c=D(t);break}}let u=o===``?null:y.exec(o),d=u===null?null:(u[1]??``).trim(),f=-1;i.forEach((e,t)=>{f===-1&&e.startsWith(`## `)&&e.includes(`处置结果`)&&(f=t)});let p=!1;if(f!==-1){let e=Math.min(i.length,f+8);for(let t=f;t<e;t+=1)if(x.test(i[t]??``)){p=!0;break}}let m=S.some(e=>t.includes(e)),h=null,g=null;if(Ne(i).length>0)try{h=Pe(t)}catch(e){g=e instanceof Error?e.message:String(e)}return{id:r.id,slug:r.slug,file:e,title:a,status:c,statusLine:o,statusLineNumber:s,pendingReason:d,hasDispositionSection:f!==-1,dispositionIsPlaceholder:p,hasEvidenceAnchorBlock:m,criteria:h,criteriaError:g,historyRefs:Fe(i,w),blockedByRefs:Fe(i,T),rawContent:t,modifiedAtMs:n}}function F(e){if(!t(e))return[];let n=i(e).filter(e=>h.test(e)).sort((e,t)=>e.localeCompare(t)),a=[];for(let t of n){let n=u(e,t);try{let e=r(n,`utf8`),i=s(n).mtimeMs,o=P(t,e,i);o!==null&&a.push(o)}catch{a.push({id:N(t)?.id??``,slug:N(t)?.slug??``,file:t,title:``,status:`unknown`,statusLine:``,statusLineNumber:0,pendingReason:null,hasDispositionSection:!1,dispositionIsPlaceholder:!1,hasEvidenceAnchorBlock:!1,criteria:null,criteriaError:null,historyRefs:[],blockedByRefs:[],rawContent:``,modifiedAtMs:0})}}return a}const Ie=/\[([0-9]{3,4})(?:-([a-z0-9-]+))?\]/g;function Le(e,t){return t.scopes.flatMap(t=>F(u(e,t.registryDir)).map(e=>({scopeKey:t.key,number:e.id,slug:e.slug})))}function Re(e,t,n){let r=n.filter(t=>t.number===e);if(r.length===0)return{kind:`unknown`,message:`引用编号 ${e} 在全部 scope 中无命中`};if((t===null?[]:r.filter(e=>e.slug===t)).length===1)return{kind:`ok`};let i=t===null?r:r.filter(e=>e.slug.startsWith(t));return i.length===1?{kind:`ok`}:i.length===0?{kind:`unknown`,message:`引用 ${e}-${t} 在 scope 候选集中无 slug 命中(编号命中:${r.map(e=>`${e.scopeKey}/${e.number}-${e.slug}`).join(`、`)})`}:{kind:`ambiguous`,message:`引用 ${e}${t===null?``:`-${t}`} 命中不唯一——候选:${i.map(e=>`${e.scopeKey}/${e.number}-${e.slug}`).join(`、`)}(请展开完整 slug 或注明 scope)`}}function ze(e){if(e.config.docs===void 0)throw Error(`配置未登记 docs 节(docs.scanRoots)——docs 引用检查显式拒绝隐式扫描面`);let t=Le(e.root,e.config),n=[],i=0;for(let a of e.config.docs.scanRoots){let o=M(u(e.root,a),{excludeGlobs:e.config.docs.exclusions.map(e=>e.glob)});i+=o.length;for(let i of o){if(!e.config.docs.includeExtensions.some(e=>i.endsWith(e)))continue;let o=r(u(e.root,a,i),`utf8`),s=He(o),c=a===``?i:`${a}/${i}`,l=new RegExp(Ie.source,`g`),d=l.exec(o);for(;d!==null;){let e=Re(d[1]??``,d[2]??null,t);if(e.kind!==`ok`){let t=Ue(s,d.index??0);n.push({file:c,line:t.line,column:t.column,rule:e.kind===`unknown`?`doc-ref-unknown`:`doc-ref-ambiguous`,message:e.message})}d=l.exec(o)}}}let a=new Map((e.config.docs.baseline??[]).map(e=>[`${e.file}::${e.rule}`,e]));if(e.ignoreBaseline===!0)return{violations:n,suppressed:0,scannedFiles:i};let o=[],s=0,c=new Set;for(let e of n){let t=`${e.file}::${e.rule}`;if(a.has(t)){s+=1,c.add(t);continue}o.push(e)}let l=[...a.entries()].filter(([e])=>!c.has(e)).map(([e,t])=>({file:e.split(`::`)[0]??``,line:0,column:0,rule:`baseline-stale`,message:`docs 基线条目已无对应现行违规——棘轮只许缩短,须同步删除该条目(收编指针:${t.issue})`}));return{violations:[...o,...l].sort((e,t)=>e.file.localeCompare(t.file)||e.rule.localeCompare(t.rule)),suppressed:s,scannedFiles:i}}function Be(e){if(e.config.docs===void 0)throw Error(`配置未登记 docs 节(docs.scanRoots)——docs 修复显式拒绝隐式扫描面`);let t=Le(e.root,e.config),n=[],i=[];for(let a of e.config.docs.scanRoots){let o=M(u(e.root,a),{excludeGlobs:e.config.docs.exclusions.map(e=>e.glob)});for(let s of o){if(!e.config.docs.includeExtensions.some(e=>s.endsWith(e)))continue;let o=r(u(e.root,a,s),`utf8`),l=[],d=new RegExp(Ie.source,`g`),f=d.exec(o);for(;f!==null;){let e=f[1]??``,n=f[2]??null;if(n!==null){let r=t.filter(t=>t.number===e&&t.slug.startsWith(n));if(r.length>1){let t=Ue(He(o),f.index??0);i.push({file:s,line:t.line,column:t.column,rule:`refused`,message:`引用 ${e}-${n} 前缀命中不唯一,无法机械归位(候选:${r.map(e=>`${e.scopeKey}/${e.number}-${e.slug}`).join(`、`)})——需人工核定`})}else r.length===1&&r[0]?.slug!==n&&l.push({start:f.index??0,end:(f.index??0)+f[0].length,replacement:`[${e}-${r[0]?.slug}]`})}f=d.exec(o)}if(l.length===0)continue;let p=o;for(let e of[...l].sort((e,t)=>t.start-e.start))p=`${p.slice(0,e.start)}${e.replacement}${p.slice(e.end)}`;e.dryRun!==!0&&p!==o?(c(u(e.root,a,s),p),n.push(s)):e.dryRun===!0&&n.push(s)}}return{fixedFiles:n,refused:i}}function Ve(t){if(t.config.docs===void 0)throw Error(`配置未登记 docs 节——无法再生 docs 基线`);if(t.issuePointer.trim()===``)return{ok:!1,error:`再生须携带非空 --issue <指针>(收编盖章)`};let n=ze({root:t.root,config:t.config,ignoreBaseline:!0}).violations,r=new Set((t.config.docs.baseline??[]).map(e=>`${e.file}::${e.rule}`)),i=n.filter(e=>!r.has(`${e.file}::${e.rule}`));if(i.length>0)return{ok:!1,error:`存在 ${i.length} 项基线外新增违规,拒绝再生(先处置新增违规后再收编存量):\n${i.slice(0,10).map(e=>`${e.file}:${e.line} [${e.rule}]`).join(`
3
3
  `)}`};let a=n.map(e=>({file:e.file,rule:e.rule,issue:t.issuePointer}));return{ok:!0,content:e(t.config,`docs`,a),entryCount:a.length}}function He(e){let t=[0];for(let n=0;n<e.length;n+=1)e[n]===`
4
4
  `&&t.push(n+1);return t}function Ue(e,t){let n=0;for(let r=0;r<e.length&&(e[r]??0)<=t;r+=1)n=r;return{line:n+1,column:t-(e[n]??0)+1}}const We=[{id:`issue-create-and-process`,description:`登记新问题到注册表并完成治理:范围判定、查重、门禁取号、证据先行、裁决门槛、TDD、单载体回填、verify-close 收口`,content:`# issue-create-and-process:登记新问题并完成治理
5
5
 
@@ -63,17 +63,17 @@ import"./rolldown-runtime-BqT_7tdF.js";import{renderBaselineRegeneratedConfig as
63
63
  `)}function Ze(e,t,n){return[`${e}`,``,`判据执行证据(证书化收口,${n}):`,...t.map(e=>`- ${e}`)].join(`
64
64
  `)}function Qe(e){try{return p(`git`,[`ls-files`,`--cached`,`--others`,`--exclude-standard`,`-z`],{cwd:e,maxBuffer:67108864}).toString(`utf8`).split(`\0`).filter(e=>e!==``).sort().join(`
65
65
  `)}catch{return M(e).join(`
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=ve(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=_e(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
- `)),{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=>O(e.glob,n))?null:`slug 段含数字(scope 政策 slugDigitPolicy 或白名单 slugDigitAllowlist 登记):${e.file}`}},{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
- `);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 Ot={立案日期:10,优先级:20,严重程度:30,状态:40,处置日期:50,所属域:60};function V(e){let t=[],n=[],r=e.length;for(let i=0;i<e.length;i+=1){let a=e[i]??``;if(a.startsWith(`## `)||a===``&&t.length>0&&i>4){r=i;break}if(a===``||a.startsWith(`# `))continue;let o=/^##\s+([^::]{1,8})\s*[::]\s*(.+)$/.exec(a);if(o!==null){t.push({key:o[1]?.trim()??``,value:o[2]?.trim()??``});continue}let s=/^(?:\*\*|- )([^*::]{1,8})(?:\*\*)?\s*[::]\s*(.+)$/.exec(a);if(s!==null){t.push({key:s[1]?.trim()??``,value:s[2]?.trim()??``});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]?.trim()??``,value:e[2]?.trim()??``})}r.length===e.length?n.push(a):n.push(...r);continue}let c=/^\|([^|]*)\|([^|]*)\|$/.exec(a.trim());if(c!==null){let r=(c[1]??``).trim(),o=(c[2]??``).trim(),s=/^:?-{2,}:?$/,l=s.test(r)&&s.test(o),u=/^\|([^|]*)\|([^|]*)\|$/.exec((e[i+1]??``).trim()),d=u!==null&&s.test((u[1]??``).trim())&&s.test((u[2]??``).trim());if(l||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=V(n);if(!r.fields.some(e=>e.key===`状态`)){if(t?.status===void 0)return{content:e,outcome:`skipped`};r.fields.push({key:`状态`,value:T[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(V(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 H(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 oe[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 Ft(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 U(e){return{高:`P1`,中:`P2`,低:`P3`,P1:`P1`,P2:`P2`,P3:`P3`}[H(e)]??null}function It(e,t){let n=e.replace(/^#\s+/,``).replace(RegExp(`^${t}\\s*(?:[-·..::]\\s*|\\s*)`),``).trim();return{line:`# ${t} - ${n}`,titleCore:n}}const W=[{pattern:/^验证(结果)?(?!口径)/,title:`处置结果/验证口径`},{pattern:/^(治理记录|治理落地记录|治理落地|落地治理|治理(落地)|治理动作|治理$)/,title:`处置结果/治理记录`},{pattern:/^(修复(?!方向)|解决方案|变更内容|处理报告|处置(?!方向))/,title:`处置结果/变更记录`}];function Lt(e){let t=[],n=-1,r=``;for(let t of W){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 Rt=[`优先级`,`状态`,`立案日期`,`所属域`,`来源`,`沿革`,`阻塞`];function zt(e,t){let n=e.split(/\r?\n/),r=V(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:[]};let o=a?`${T[t.status??`red`]}(存量清偿定档:原案无状态行,依结案内容人工定档)`:H(r.fields[i??0]?.value??``);if(!a&&E(`状态: ${o}`)!==`unknown`)return{outcome:`unchanged`,content:e,message:`状态行已是规范五态形态`,transformations:[]};let s=[],c=r.fields.map(e=>({key:e.key,value:H(e.value)}));a&&(c.push({key:`状态`,value:o}),s.push({kind:`status-canonicalized`,detail:`<无状态行> → ${o}(--status 注入,人工定档)`}));let l=c.findIndex(e=>e.key===`立案日期`),u=c.findIndex(e=>e.key===`日期`);if(l===-1&&u!==-1){let e=c[u];e!==void 0&&(c[u]={key:`立案日期`,value:e.value},s.push({kind:`field-alias`,detail:`日期 → 立案日期(${e.value})`}))}if(!c.some(e=>e.key===`立案日期`)){if(t.defaultFilingDate===void 0)return{outcome:`skipped`,content:e,message:`缺立案日期且未给回填缺省——交人工`,transformations:[]};c.push({key:`立案日期`,value:t.defaultFilingDate}),s.push({kind:`required-backfilled`,detail:`立案日期 ← ${t.defaultFilingDate}`})}let d=c.findIndex(e=>e.key===`优先级`);if(d!==-1){let e=c[d]?.value??``,t=U(e);t!==null&&t!==e&&(c[d]={key:`优先级`,value:t},s.push({kind:`priority-mapped`,detail:`优先级 ${e} ${t}`}))}else{let n=c.find(e=>e.key===`严重程度`),r=(n===void 0?null:U(n.value))??t.defaultPriority??null;if(r===null)return{outcome:`skipped`,content:e,message:`缺优先级且未给回填缺省——交人工`,transformations:[]};c.push({key:`优先级`,value:r}),s.push({kind:n===void 0?`priority-backfilled`:`priority-mapped`,detail:`优先级 ← ${r}${n===void 0?`(缺省回填)`:`(严重程度 ${n.value})`}`})}let f=t.status===`green`?`green`:`red`,p=a?{value:o,tier:f,word:`<无状态行>`}:Ft(o);if(p===null)return{outcome:`skipped`,content:e,message:`状态值「${o}」不可机械迁移(冻结/取消无据/黄灯无因/词表未识别)——交人工`,transformations:[]};let m=p.tier===`green`,h=n.slice(r.bodyStartIndex),g=m?Lt(h):{lines:h,transformations:[],placeholder:!1};h=g.lines,s.push(...g.transformations);let _=!a&&g.placeholder?`🟡 处理中(历史标记已处置但验证口径为占位,清偿时待核实;原「${p.word}」)`:p.value;a||(g.placeholder?s.push({kind:`status-downgraded-placeholder`,detail:`${o} → 🟡 处理中(处置段占位降级)`}):s.push({kind:`status-canonicalized`,detail:`${o} → ${p.value}`}));let v=c.findIndex(e=>e.key===`状态`);if(v!==-1&&(c[v]={key:`状态`,value:_}),!c.some(e=>e.key===`来源`)){if(t.defaultSource===void 0)return{outcome:`skipped`,content:e,message:`缺来源且未给回填缺省——交人工`,transformations:[]};c.push({key:`来源`,value:t.defaultSource}),s.push({kind:`required-backfilled`,detail:`来源 ← 缺省回填`})}c.some(e=>e.key===`所属域`)||(c.push({key:`所属域`,value:t.scopeTitle}),s.push({kind:`required-backfilled`,detail:`所属域 ← ${t.scopeTitle}`}));let y=n.findIndex(e=>e.startsWith(`# `));if(y===-1)return{outcome:`skipped`,content:e,message:`无一级标题——交人工`,transformations:[]};let b=It(n[y]??``,t.number);b.line!==(n[y]??``)&&s.push({kind:`h1-numbered`,detail:`${n[y]} → ${b.line}`});let ee=[...Rt.flatMap(e=>c.filter(t=>t.key===e)),...c.filter(e=>!Rt.includes(e.key))],x=[b.line,``,...ee.map(e=>`**${e.key}**: ${e.value}`),...r.residuals.length>0?[``,...r.residuals]:[],``,...h].join(`
70
- `);return x===e?{outcome:`unchanged`,content:e,message:`已是规范形态`,transformations:[]}:{outcome:`rewritten`,content:x,message:`存量头部已清偿为规范形态`,transformations:s}}const Bt=/^([0-9]{3,4})-.+\.md$/;function Vt(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 Ht(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(`## `)&&W.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]??``).trim(),o=H(e[2]??``);!n.includes(a)&&!t.includes(o)&&(r=!1)}if(r)continue}let c=/^(?:\*\*|- |## )([^*::]{1,20})(?:\*\*)?\s*[::]\s*(.+)$/.exec(a);if(c!==null){let e=(c[1]??``).trim(),r=H(c[2]??``);if(n.includes(e)||t.includes(r))continue}r.push(o.slice(0,60))}return r}function Ut(e){let t=e.file.split(`/`).pop()??``,n=Bt.exec(t);if(n===null)return{file:e.file,outcome:`skipped`,message:`文件名不属注册表编号形态(NNNN-slug.md)`,content:``,transformations:[]};let i=Vt(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=zt(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=Ht(a,o.content,[`状态`,`日期`,`优先级`]);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 G(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 K(e){let t=/^\d+/.exec(e);return t===null?null:Number.parseInt(t[0]??``,10)}function q(e){let t=new Set;for(let n of e.basenames){let r=G(n,e.rule);r!==null&&t.add(r)}if(t.size===0)return{ok:!1,error:`该范围当前无编号文件,无法推断位数——请人工定号后落盘`};let n=``;for(let e of t)(K(e)??0)>(K(n)||0)&&(n=e);if(n===``)return{ok:!1,error:`该范围无数字前缀键,无法取号`};let r=n.length,i=new Set(e.reserved),a=0,o=0,s=(K(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 Wt(e){let t=/^\d+[-._ ](.+)\.[^.]+$/.exec(e);return t===null?null:t[1]??``}function Gt(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 Kt(e){let t=[],n=new Map;for(let t of e.basenames){let r=G(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&&Gt(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=Wt(r);if(i===null||i===``||!/\d/.test(i))continue;let a=e.toRepoRelative(r);e.slugDigitAllowlist.some(e=>O(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 qt(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=>O(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 J={kind:`numericPrefix`};function Y(e,t){return j(e,[t]).map(e=>e.split(`/`).pop()??``)}function Jt(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=q({basenames:Y(e.root,t.registryDir),rule:J,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=q({basenames:Y(e.root,e.dirRel??``),rule:J,reserved:i});return a.ok?{ok:!0,number:a.number,target:e.dirRel??``,skippedOccupied:a.skippedOccupied,skippedReserved:a.skippedReserved}:a}function Yt(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=Y(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(...Kt({scopeKey:i.key,basenames:t,rule:J,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 Xt(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:qt({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 X=`<!-- issue-file-format-fixture:start -->`,Z=`<!-- issue-file-format-fixture:end -->`,Q=`docs/guides/issue-file-format.md`;function Zt(){let e=l(f(import.meta.url.replace(`file://`,``)));for(let n=0;n<10;n+=1){let n=u(e,Q);if(t(n))return n;let r=l(e);if(r===e)break;e=r}throw Error(`未定位到格式指南:${Q}(自模块位置向上 10 层内)`)}function Qt(){return r(Zt(),`utf8`)}function $t(e){let t=e.indexOf(X),n=e.indexOf(Z);if(t===-1)throw Error(`指南活样板起点标记缺席:${X}`);if(n===-1)throw Error(`指南活样板终点标记缺席:${Z}`);if(n<t)throw Error(`指南活样板标记次序颠倒(终点在起点之前)`);return e.slice(t+40,n).replace(/^\n+/,``).replace(/\n+$/,``)}const $=[`## 一、问题动机`,``,`> <问题原文逐字记录,禁止转述改写>`,``,`客观证据(报错/复现步骤/涉及文件/日志路径):`,`- <证据>`,``].join(`
71
- `),en=[`## 二、现状与证据`,``,`<排查链路与实证;无法确认根因时如实标注「根因待治理时核实」>`,``].join(`
72
- `),tn=[`## 三、处置方向`,``,`【1】备选方案和分析`,`- <备选>:<分析>`,``,`【2】推荐方案和分析`,`- <推荐>:<分析;能自决的直接执行,裁决类停下等用户裁定>`,``].join(`
73
- `),nn=[`## 四、处置结果/验证口径`,``,`<随治理进展回填;判据以 criteria 围栏块声明;收口由 verify-close 回填证据锚点>`,``].join(`
74
- `);function rn(e){return e.map(e=>e.slug?`[${e.number}](./${e.number}-${e.slug}.md)`:`[${e.number}]`).join(`;`)}function an(){return[`# <NNNN> - <一句话标题:问题是什么,禁笼统词>`,``,`**优先级**: <P1|P2|P3>`,`**状态**: ${T.red}`,`**立案日期**: <YYYY-MM-DD>`,`**所属域**: <scope title>`,`**来源**: <问题原文出处(用户裁定/会话记录/自动巡检 + 日期)>`,`**沿革**: <可选:前序 issue 引用,如 [0035](./0035-<slug>.md)>`,`**阻塞**: <可选:被阻塞于哪些 issue;全部 🟢 后方可收口>`,``,$,en,tn,nn].join(`
75
- `)}function on(e){let t=[`# ${e.number} - ${e.title}`,``,`**优先级**: ${e.priority}`,`**状态**: ${T.red}`,`**立案日期**: ${e.date}`,`**所属域**: ${e.scopeTitle}`,`**来源**: ${e.source}`];return e.historyRefs!==void 0&&e.historyRefs.length>0&&t.push(`**${C}**: ${rn(e.historyRefs)}`),e.blockedByRefs!==void 0&&e.blockedByRefs.length>0&&t.push(`**${w}**: ${rn(e.blockedByRefs)}`),t.push(``),[t.join(`
76
- `),$,en,tn,nn].join(`
77
- `)}function sn(){return["```criteria",`# 一行一判据:label|channel|cwd|command(四段竖线分隔,段内禁竖线)`,`# channel 限字母数字起首的 [A-Za-z0-9._-];cwd 相对仓库根;command 为退出码即判据的自动化命令`,`# summary 行唯一且非空——真跑收口 --criteria-from-issue 的机器可读载体`,`summary: 示例:单包测试全绿`,`单包测试|test|packages/demo|bun run test`,"```",``].join(`
78
- `)}function cn(e,t){let n=t===null?"- 标准模板:`lzi-issues template`(字段契约 `--format json`);完整格式规范见 lzi-issues 仓 docs/guides/issue-file-format.md(本仓未携带指南文件,不落链接)":"- 标准模板:`lzi-issues template`;完整格式规范:[issue-file-format]("+t+`)`;return[`# ${e} issue 注册表`,``,"本目录是 lzi-issues 注册表(`NNNN-<slug>.md`,目录即编号命名空间,编号独立序列)。",``,`## 建档`,``,"- `lzi-issues create --title <标题> --scope <key>`(编号走门禁取号,禁止手工定号)",n,``,`## 状态行(处理情况第一入口)`,``,`- ${T.red}:待处理`,`- ${T.yellow}(须括注 ≥4 字挂起原因)`,`- ${T.green}(须处置段 + 证据锚点;收口走 \`lzi-issues verify-close\`)`,`- ${T.frozen}(仅经 \`lzi-issues freeze\`,理由须含「用户裁定」)`,`- ${T.canceled}(须括注取消原因)`,``,`## 正文四段`,``,`一、问题动机 → 二、现状与证据 → 三、处置方向(【1】备选方案和分析 / 【2】推荐方案和分析)→ 四、处置结果/验证口径`,``].join(`
79
- `)}const ln=[{name:`number`,required:!0,description:`scope 内编号,4 位零填充,由编号门禁取号分配(写入时刻确定)`},{name:`slug`,required:!0,description:`ASCII kebab slug(小写字母/数字/连字符,禁中文),slug 段默认禁数字(slugDigitPolicy)`},{name:`title`,required:!0,description:`一句话标题:问题是什么,禁笼统词`},{name:`priority`,required:!0,description:`优先级,P1 | P2 | P3`},{name:`status`,required:!0,description:`状态行五态;建档固定 🔴 待处理,流转走工具(verify-close / freeze 等)`},{name:`立案日期`,required:!0,description:`YYYY-MM-DD`},{name:`所属域`,required:!0,description:`config 登记的 scope title`},{name:`来源`,required:!0,description:`问题原文出处(用户裁定 / 会话记录 / 自动巡检 + 日期)`},{name:`沿革`,required:!1,description:`前序 issue 引用,markdown 相对链接或纯编号形态`},{name:`阻塞`,required:!1,description:`被阻塞于哪些 issue;全部 🟢 后方可收口(blockingMustBeGreen 门禁)`}];export{z as ADJUDICATION_KEYWORD,g as ASCII_KEBAB_SLUG_PATTERN,w as BLOCKING_LINE_KEY,T as CANONICAL_STATUS_LABELS,St as CORE_LINT_RULES,S as CRITERIA_CHANNEL_PATTERN,ie as CRITERIA_FENCE_CLOSE_PATTERN,re as CRITERIA_FENCE_OPEN_PATTERN,W as DISPOSITION_CANDIDATES,x as DISPOSITION_PLACEHOLDER_PATTERN,te as DISPOSITION_PLACEHOLDER_WINDOW_LINES,ee as DISPOSITION_TITLE_KEYWORD,ne as EVIDENCE_ANCHOR_MARKERS,Z as GUIDE_FIXTURE_END_MARK,X as GUIDE_FIXTURE_START_MARK,C as HISTORY_LINE_KEY,J as ISSUES_KEY_RULE,Q as ISSUE_FILE_FORMAT_GUIDE_RELATIVE,se as ISSUE_REF_TOKEN_PATTERN,oe as LEGACY_STATUS_VOCABULARY,ae as META_LINE_PREFIX_SOURCE_TEMPLATE,D as MiniGlobError,b as PENDING_REASON_PATTERN,h as REGISTRY_FILE_PATTERN,v as STATUS_LINE_LOCATE_PATTERN,_ as STATUS_LINE_PREFIX_SOURCE,y as STATUS_LINE_SCAN_LINES,ln as TEMPLATE_FIELDS,it as acquireRunLock,I as applyGreenFlip,qt as auditCoverage,ue as buildMetaLineLocatePattern,It as canonicalizeH1,Ft as canonicalizeStatusValue,R as certificatePath,B as classifyIssue,E as classifyStatusLine,H as cleanValue,Te as compileMiniGlob,L as computeCriterionFingerprint,q as computeNextNumber,Dt as deriveEntriesFromViolations,De as deriveWalkPrefixes,ot as evidenceCloseFlow,G as extractFileKey,le as extractIssueRefTokens,Wt as extractSlugSegment,$e as findCertificate,ve as findPendingWord,dt as freezeIssue,K as keyLeadingNumber,Ke as listPrompts,Qt as loadIssueFileFormatGuide,he as locateDispositionText,Zt as locateIssueFileFormatGuide,U as mapPriorityValue,O as matchMiniGlob,zt as migrateLegacyCore,Ut as migrateLegacyFile,At as normalizeHeader,Mt as normalizeHeaderFile,Pe as parseCriteriaBlock,V as parseHeaderDialect,P as parseIssueDoc,N as parseRegistryFileName,_e as readEvidence,ge as readEvidenceAnchors,ye as readPendingReason,bt as registerLintRulePack,sn as renderCriteriaBlockExample,Xe as renderEvidenceCloseBlock,on as renderIssueTemplate,an as renderIssueTemplateSkeleton,cn as renderRegistryReadmeStub,Ze as renderRerunEvidenceBlock,lt as rerunCloseFlow,ct as resolveCloseGates,nt as runCriterionViaVault,ze as runDocsCheck,Be as runDocsFix,_t as runHealth,Ct as runLint,Xt as runNumberingAudit,Yt as runNumberingCheck,Jt as runNumberingNext,vt as runTriage,Ve as runWriteDocsBaseline,Et as runWriteLintBaseline,Tt as scanOrphanSidecars,F as scanRegistryDir,Kt as scanScopeForFindings,qe as showPrompt,$t as sliceGuideFixtureSample,ft as unfreezeIssue,j as walkFilesUnderPrefixes,M as walkFilesUnderRoots};
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
+ `)),{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
+ `);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(`
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
+ `),ln=[`## 二、现状与证据`,``,`<排查链路与实证;无法确认根因时如实标注「根因待治理时核实」>`,``].join(`
72
+ `),un=[`## 三、处置方向`,``,`【1】备选方案和分析`,`- <备选>:<分析>`,``,`【2】推荐方案和分析`,`- <推荐>:<分析;能自决的直接执行,裁决类停下等用户裁定>`,``].join(`
73
+ `),dn=[`## 四、处置结果/验证口径`,``,`<随治理进展回填;判据以 criteria 围栏块声明;收口由 verify-close 回填证据锚点>`,``].join(`
74
+ `);function fn(e){return e.map(e=>e.slug?`[${e.number}](./${e.number}-${e.slug}.md)`:`[${e.number}]`).join(`;`)}function pn(){return[`# <NNNN> - <一句话标题:问题是什么,禁笼统词>`,``,`**优先级**: <P1|P2|P3>`,`**状态**: ${E.red}`,`**立案日期**: <YYYY-MM-DD>`,`**所属域**: <scope title>`,`**来源**: <问题原文出处(用户裁定/会话记录/自动巡检 + 日期)>`,`**沿革**: <可选:前序 issue 引用,如 [0035](./0035-<slug>.md)>`,`**阻塞**: <可选:被阻塞于哪些 issue;全部 🟢 后方可收口>`,``,cn,ln,un,dn].join(`
75
+ `)}function mn(e){let t=[`# ${e.number} - ${e.title}`,``,`**优先级**: ${e.priority}`,`**状态**: ${E.red}`,`**立案日期**: ${e.date}`,`**所属域**: ${e.scopeTitle}`,`**来源**: ${e.source}`];return e.historyRefs!==void 0&&e.historyRefs.length>0&&t.push(`**${w}**: ${fn(e.historyRefs)}`),e.blockedByRefs!==void 0&&e.blockedByRefs.length>0&&t.push(`**${T}**: ${fn(e.blockedByRefs)}`),t.push(``),[t.join(`
76
+ `),cn,ln,un,dn].join(`
77
+ `)}function hn(){return["```criteria",`# 一行一判据:label|channel|cwd|command(四段竖线分隔,段内禁竖线)`,`# channel 限字母数字起首的 [A-Za-z0-9._-];cwd 相对仓库根;command 为退出码即判据的自动化命令`,`# summary 行唯一且非空——真跑收口 --criteria-from-issue 的机器可读载体`,`summary: 示例:单包测试全绿`,`单包测试|test|packages/demo|bun run test`,"```",``].join(`
78
+ `)}function gn(e,t){let n=t===null?"- 标准模板:`lzi-issues template`(字段契约 `--format json`);完整格式规范见 lzi-issues 仓 docs/guides/issue-file-format.md(本仓未携带指南文件,不落链接)":"- 标准模板:`lzi-issues template`;完整格式规范:[issue-file-format]("+t+`)`;return[`# ${e} issue 注册表`,``,"本目录是 lzi-issues 注册表(`NNNN-<slug>.md`,目录即编号命名空间,编号独立序列)。",``,`## 建档`,``,"- `lzi-issues create --title <标题> --scope <key>`(编号走门禁取号,禁止手工定号)",n,``,`## 状态行(处理情况第一入口)`,``,`- ${E.red}:待处理`,`- ${E.yellow}(须括注 ≥4 字挂起原因)`,`- ${E.green}(须处置段 + 证据锚点;收口走 \`lzi-issues verify-close\`)`,`- ${E.frozen}(仅经 \`lzi-issues freeze\`,理由须含「用户裁定」)`,`- ${E.canceled}(须括注取消原因)`,``,`## 正文四段`,``,`一、问题动机 → 二、现状与证据 → 三、处置方向(【1】备选方案和分析 / 【2】推荐方案和分析)→ 四、处置结果/验证口径`,``].join(`
79
+ `)}const _n=[{name:`number`,required:!0,description:`scope 内编号,4 位零填充,由编号门禁取号分配(写入时刻确定)`},{name:`slug`,required:!0,description:`ASCII kebab slug(小写字母/数字/连字符,禁中文),slug 段默认禁数字(slugDigitPolicy)`},{name:`title`,required:!0,description:`一句话标题:问题是什么,禁笼统词`},{name:`priority`,required:!0,description:`优先级,P1 | P2 | P3`},{name:`status`,required:!0,description:`状态行五态;建档固定 🔴 待处理,流转走工具(verify-close / freeze 等)`},{name:`立案日期`,required:!0,description:`YYYY-MM-DD`},{name:`所属域`,required:!0,description:`config 登记的 scope title`},{name:`来源`,required:!0,description:`问题原文出处(用户裁定 / 会话记录 / 自动巡检 + 日期)`},{name:`沿革`,required:!1,description:`前序 issue 引用,markdown 相对链接或纯编号形态`},{name:`阻塞`,required:!1,description:`被阻塞于哪些 issue;全部 🟢 后方可收口(blockingMustBeGreen 门禁)`}];export{z as ADJUDICATION_KEYWORD,g as ASCII_KEBAB_SLUG_PATTERN,T as BLOCKING_LINE_KEY,E as CANONICAL_STATUS_LABELS,St as CORE_LINT_RULES,re as CRITERIA_CHANNEL_PATTERN,ne as CRITERIA_FENCE_CLOSE_PATTERN,C as CRITERIA_FENCE_OPEN_PATTERN,K as DISPOSITION_CANDIDATES,x as DISPOSITION_PLACEHOLDER_PATTERN,te as DISPOSITION_PLACEHOLDER_WINDOW_LINES,b as DISPOSITION_TITLE_KEYWORD,S as EVIDENCE_ANCHOR_MARKERS,$ as GUIDE_FIXTURE_END_MARK,Q as GUIDE_FIXTURE_START_MARK,V as HEADING_ALONE_METADATA_KEYS,w as HISTORY_LINE_KEY,X as ISSUES_KEY_RULE,rn as ISSUE_FILE_FORMAT_GUIDE_RELATIVE,oe as ISSUE_REF_TOKEN_PATTERN,ae as LEGACY_STATUS_VOCABULARY,ie as META_LINE_PREFIX_SOURCE_TEMPLATE,O as MiniGlobError,y as PENDING_REASON_PATTERN,h as REGISTRY_FILE_PATTERN,v as STATUS_LINE_LOCATE_PATTERN,_ as STATUS_LINE_PREFIX_SOURCE,ee as STATUS_LINE_SCAN_LINES,_n as TEMPLATE_FIELDS,it as acquireRunLock,I as applyGreenFlip,$t as auditCoverage,It as backfillRequiredFields,le as buildMetaLineLocatePattern,Ft as canonicalizeH1,W as canonicalizeStatusValue,R as certificatePath,B as classifyIssue,D as classifyStatusLine,U as cleanValue,we as compileMiniGlob,L as computeCriterionFingerprint,Y as computeNextNumber,Dt as deriveEntriesFromViolations,De as deriveWalkPrefixes,ot as evidenceCloseFlow,q as extractFileKey,ce as extractIssueRefTokens,Xt as extractSlugSegment,$e as findCertificate,_e as findPendingWord,dt as freezeIssue,J as keyLeadingNumber,Ke as listPrompts,on as loadIssueFileFormatGuide,me as locateDispositionText,an as locateIssueFileFormatGuide,G as mapPriorityValue,k as matchMiniGlob,Gt as migrateLegacyCore,Yt as migrateLegacyFile,At as normalizeHeader,Mt as normalizeHeaderFile,Pe as parseCriteriaBlock,H as parseHeaderDialect,P as parseIssueDoc,N as parseRegistryFileName,ge as readEvidence,he as readEvidenceAnchors,ve as readPendingReason,bt as registerLintRulePack,hn as renderCriteriaBlockExample,Xe as renderEvidenceCloseBlock,mn as renderIssueTemplate,pn as renderIssueTemplateSkeleton,gn as renderRegistryReadmeStub,Ze as renderRerunEvidenceBlock,lt as rerunCloseFlow,ct as resolveCloseGates,nt as runCriterionViaVault,ze as runDocsCheck,Be as runDocsFix,_t as runHealth,Ct as runLint,nn as runNumberingAudit,tn as runNumberingCheck,en as runNumberingNext,vt as runTriage,Ve as runWriteDocsBaseline,Et as runWriteLintBaseline,Tt as scanOrphanSidecars,F as scanRegistryDir,Qt as scanScopeForFindings,qe as showPrompt,sn as sliceGuideFixtureSample,ft as unfreezeIssue,j as walkFilesUnderPrefixes,M as walkFilesUnderRoots};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@longzai-intelligence-issues/ledger",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
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.2"
30
+ "@longzai-intelligence-issues/config": "0.0.3"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/bun": "^1.4.2"
@@ -172,6 +172,30 @@ describe('runLint 核心规则', () => {
172
172
  ).toBe(true);
173
173
  });
174
174
 
175
+ test('duplicate-metadata-key:头部区规范键重复计违规', () => {
176
+ writeIssue(
177
+ '0014-dup-meta.md',
178
+ [
179
+ '# 0014 - 样例',
180
+ '',
181
+ '**状态**: 🔴 待处理',
182
+ '**来源**: 会话记录',
183
+ '',
184
+ '- **状态**:未处理(已登记,待治理)',
185
+ '',
186
+ '## 一、问题动机',
187
+ ].join('\n'),
188
+ );
189
+
190
+ const result = runLint({ root: FIXTURE_ROOT, config: parseConfig() });
191
+
192
+ expect(
193
+ result.violations.some(
194
+ (v) => v.rule === 'duplicate-metadata-key' && v.file.includes('0014-dup-meta'),
195
+ ),
196
+ ).toBe(true);
197
+ });
198
+
175
199
  test('slug 白名单豁免', () => {
176
200
  const result = runLint({
177
201
  root: FIXTURE_ROOT,
@@ -118,6 +118,40 @@ const BOLD_DIALECT_RED = [
118
118
  '正文。',
119
119
  ].join('\n');
120
120
 
121
+ /**
122
+ * 引用+粗体复合方言(academy 形态:`> **键**: 值` 逐行)样例
123
+ */
124
+ const QUOTE_BOLD_DIALECT = [
125
+ '# 0001 — auth 迁移标准化',
126
+ '',
127
+ '> **状态**: 已修复',
128
+ '> **日期**: 2026-08-04',
129
+ '> **责任方**: academy 项目',
130
+ '',
131
+ '## 迁移目标',
132
+ '',
133
+ '正文。',
134
+ ].join('\n');
135
+
136
+ /**
137
+ * 标题式隔行值方言(oxlint 形态:`## 键` 单独成行 + 下一非空行为值)样例
138
+ */
139
+ const HEADING_ALONE_DIALECT = [
140
+ '# 0001 — ignorePatterns 未生效',
141
+ '',
142
+ '## 状态',
143
+ '',
144
+ '已修复(未发布)',
145
+ '',
146
+ '## 日期',
147
+ '',
148
+ '2026-08-01',
149
+ '',
150
+ '## 现象',
151
+ '',
152
+ '正文。',
153
+ ].join('\n');
154
+
121
155
  beforeEach(() => {
122
156
  rmSync(FIXTURE_ROOT, { recursive: true, force: true });
123
157
  });
@@ -162,6 +196,34 @@ describe('migrateLegacyFile 存量清偿(dry-run 只读)', () => {
162
196
  expect(result.content.includes('| 元数据 | 内容 |')).toBe(false);
163
197
  });
164
198
 
199
+ test('引用+粗体复合方言(> **键**: 值):键清粗体后入字段,状态词命中绿系', () => {
200
+ writeIssue('0001-quote-bold-dialect.md', QUOTE_BOLD_DIALECT);
201
+
202
+ const result = migrateLegacyFile(input(`${REGISTRY_REL}/0001-quote-bold-dialect.md`));
203
+
204
+ expect(result.outcome).toBe('rewritten');
205
+ expect(result.content).toContain('**状态**: 🟢 已处置(原「已修复」)');
206
+ expect(result.content).toContain('**立案日期**: 2026-08-04');
207
+ expect(result.content).toContain('**责任方**: academy 项目');
208
+ expect(result.content).toContain('## 迁移目标');
209
+ expect(result.content.startsWith('# 0001 - auth 迁移标准化')).toBe(true);
210
+ });
211
+
212
+ test('标题式隔行值方言(## 键 + 下一非空行):键值配对入字段且键行被消费', () => {
213
+ writeIssue('0001-heading-alone-dialect.md', HEADING_ALONE_DIALECT);
214
+
215
+ const result = migrateLegacyFile(input(`${REGISTRY_REL}/0001-heading-alone-dialect.md`));
216
+
217
+ expect(result.outcome).toBe('rewritten');
218
+ expect(result.content).toContain('未发布');
219
+ expect(result.content).toContain('原「已修复」');
220
+ expect(result.content).toContain('**立案日期**: 2026-08-01');
221
+ expect(result.content.includes('## 状态')).toBe(false);
222
+ expect(result.content.includes('## 日期')).toBe(false);
223
+ expect(result.content).toContain('## 现象');
224
+ expect(result.content.startsWith('# 0001 - ignorePatterns')).toBe(true);
225
+ });
226
+
165
227
  test('粗体旧式:红灯映射 + H1 补编号 + 无验证段红灯不追加处置段', () => {
166
228
  writeIssue('0001-streamablefile-typed-response.md', BOLD_DIALECT_RED);
167
229
 
@@ -483,6 +545,162 @@ describe('migrateLegacyFile 存量清偿(dry-run 只读)', () => {
483
545
  );
484
546
  });
485
547
 
548
+ test('列表+粗体复合方言(- **键**: 值)解析为字段,原始语义保留且不落残留块', () => {
549
+ writeIssue(
550
+ '0340-list-bold-compound.md',
551
+ [
552
+ '# 静态导出产物托管纪律未登记',
553
+ '',
554
+ '- **严重度**:信息',
555
+ '- **状态**:未处理(已登记,待治理)',
556
+ '- **发现**:2026-08-24 issue 022 治理中的同类排查',
557
+ '',
558
+ '## 问题描述',
559
+ '',
560
+ '正文。',
561
+ ].join('\n'),
562
+ );
563
+
564
+ const result = migrateLegacyFile({
565
+ ...input(`${REGISTRY_REL}/0340-list-bold-compound.md`),
566
+ defaultFilingDate: '2026-08-24',
567
+ });
568
+
569
+ expect(result.outcome).toBe('rewritten');
570
+ expect(result.content).toContain('**状态**: 🔴 待处理(已登记,待治理;原「未处理」)');
571
+ expect(result.content).toContain('**严重度**: 信息');
572
+ expect(result.content).toContain('**发现**: 2026-08-24 issue 022 治理中的同类排查');
573
+ expect(result.content).not.toMatch(/^- \*\*/m);
574
+ });
575
+
576
+ test('污染修复:规范头部与体首残留元信息块收敛(键去重、注入定档让位原始语义)', () => {
577
+ writeIssue(
578
+ '0341-polluted-converge.md',
579
+ [
580
+ '# 0341 - 静态导出产物托管纪律未登记',
581
+ '',
582
+ '**优先级**: P2',
583
+ '**状态**: 🔴 待处理(存量清偿定档:原案无状态行,依结案内容人工定档)',
584
+ '**立案日期**: 2026-08-24',
585
+ '**所属域**: 项目全局',
586
+ '**来源**: 格式清偿迁移回填(2026-09-14):原案未登记来源',
587
+ '',
588
+ '- **严重度**:信息',
589
+ '- **状态**:未处理(已登记,待治理)',
590
+ '- **发现**:2026-08-24 issue 022 治理中的同类排查',
591
+ '',
592
+ '## 问题描述',
593
+ '',
594
+ '正文。',
595
+ ].join('\n'),
596
+ );
597
+
598
+ const result = migrateLegacyFile(input(`${REGISTRY_REL}/0341-polluted-converge.md`));
599
+
600
+ expect(result.outcome).toBe('rewritten');
601
+ expect(result.content).toContain('**状态**: 🔴 待处理(已登记,待治理;原「未处理」)');
602
+ expect(result.content).toContain('**严重度**: 信息');
603
+ expect(result.content).toContain('**发现**: 2026-08-24 issue 022 治理中的同类排查');
604
+ expect(result.content).not.toMatch(/存量清偿定档:原案无状态行/);
605
+ expect(result.content).not.toMatch(/^- \*\*(状态|严重度|发现)/m);
606
+ expect(result.content.match(/\*\*状态\*\*/g)).toHaveLength(1);
607
+
608
+ /**
609
+ * 收敛幂等:第一轮产物落盘后二轮 unchanged
610
+ */
611
+ const landing = migrateLegacyFile({
612
+ ...input(`${REGISTRY_REL}/0341-polluted-converge.md`),
613
+ dryRun: false,
614
+ });
615
+
616
+ expect(landing.outcome).toBe('rewritten');
617
+
618
+ const second = migrateLegacyFile(input(`${REGISTRY_REL}/0341-polluted-converge.md`));
619
+
620
+ expect(second.outcome).toBe('unchanged');
621
+ });
622
+
623
+ test('体首非元信息列表不被吸收(正文证据列表原样保留)', () => {
624
+ writeIssue(
625
+ '0342-body-bullet-kept.md',
626
+ [
627
+ '# 0342 - 样例',
628
+ '',
629
+ '**优先级**: P2',
630
+ '**状态**: 🔴 待处理',
631
+ '**立案日期**: 2026-08-24',
632
+ '**所属域**: 项目全局',
633
+ '**来源**: 会话记录',
634
+ '',
635
+ '- **next.config.ts:7** — 注释明示静态导出(正文证据,非元信息)',
636
+ '- **out/** 已被 gitignore(正文证据)',
637
+ '',
638
+ '## 问题描述',
639
+ '',
640
+ '正文。',
641
+ ].join('\n'),
642
+ );
643
+
644
+ const result = migrateLegacyFile(input(`${REGISTRY_REL}/0342-body-bullet-kept.md`));
645
+
646
+ expect(result.outcome).toBe('unchanged');
647
+ expect(result.content).toContain(
648
+ '- **next.config.ts:7** — 注释明示静态导出(正文证据,非元信息)',
649
+ );
650
+ });
651
+
652
+ test('同键多值合并:重复关联行并值为分号单行,不丢链接', () => {
653
+ writeIssue(
654
+ '0343-dup-join.md',
655
+ [
656
+ '# 0343 - 样例',
657
+ '',
658
+ '**状态**: 🟢 已处置(原「已治理」)',
659
+ '**立案日期**: 2026-06-13',
660
+ '**所属域**: 项目全局',
661
+ '**来源**: 会话记录',
662
+ '**关联**: [ADR-0010](../decisions/0010-form-error-no-document-flow-shift.md)',
663
+ '**关联**: [表单错误提示双重反馈机制规格](../specs/spec-20260510-form-error-tooltip-feedback/spec.md)',
664
+ '',
665
+ '## 验证结果',
666
+ '',
667
+ '验证正文。',
668
+ ].join('\n'),
669
+ );
670
+
671
+ const result = migrateLegacyFile(input(`${REGISTRY_REL}/0343-dup-join.md`));
672
+
673
+ expect(result.outcome).toBe('rewritten');
674
+ expect(result.content).toContain(
675
+ '**关联**: [ADR-0010](../decisions/0010-form-error-no-document-flow-shift.md);[表单错误提示双重反馈机制规格](../specs/spec-20260510-form-error-tooltip-feedback/spec.md)',
676
+ );
677
+ expect(result.content.match(/\*\*关联\*\*/g)).toHaveLength(1);
678
+ });
679
+
680
+ test('超长状态拆分:词表命中时长说明落处置摘要字段、状态行保持短规范', () => {
681
+ writeIssue(
682
+ '0344-long-status-split.md',
683
+ [
684
+ '# 0344 - 样例',
685
+ '',
686
+ '> 日期:2026-08-04',
687
+ '> 状态:**已修复**。删除 `src/index.ts` 源码 shebang,由 `lzi-builder.config.ts` 的 banner 作为唯一 shebang 来源,避免双 shebang 导致 node 以注释行开头的解释器路径执行失败。',
688
+ '',
689
+ '## 现象',
690
+ '',
691
+ '正文。',
692
+ ].join('\n'),
693
+ );
694
+
695
+ const result = migrateLegacyFile(input(`${REGISTRY_REL}/0344-long-status-split.md`));
696
+
697
+ expect(result.outcome).toBe('rewritten');
698
+ expect(result.content).toContain('**状态**: 🟢 已处置(原「已修复」)');
699
+ expect(result.content).toContain('**处置摘要**: 已修复。删除 `src/index.ts` 源码 shebang');
700
+ expect(result.content).toContain('banner 作为唯一 shebang 来源');
701
+ expect(result.content).toContain('## 现象');
702
+ });
703
+
486
704
  test('幂等:对已规范产物重跑 unchanged', () => {
487
705
  writeIssue('0400-roles-matrix-deny-divergence.md', LIST_DIALECT_GREEN);
488
706