/** Static audit of REA-recovered artifacts only. Does not execute the expert or its scripts. */ import fs from 'node:fs' import path from 'node:path' import crypto from 'node:crypto' import assert from 'node:assert/strict' import {parseDocument} from 'yaml' const directory='.tmp/rea-project-manager-recovered-20261016' const evidence=JSON.parse(fs.readFileSync(path.join(directory,'evidence-manifest.json'),'utf8')) const sha=bytes=>crypto.createHash('sha256').update(bytes).digest('hex') assert.equal(evidence.rootSha256,'304805c85b87e8266294fb3aaf283d45fc71d7977af064fcb1eed1199e9389e6') const byPath=new Map(evidence.files.map(file=>[file.path,file])) function text(relative){const item=byPath.get(relative);if(!item)return null;const bytes=fs.readFileSync(path.join(directory,relative));assert.equal(sha(bytes),item.sha256);assert.equal(bytes.length,item.bytes);return new TextDecoder('utf-8',{fatal:true}).decode(bytes)} function source(relative){const{path:filename,sha256,evidenceId,retainedExport}=byPath.get(relative);return{path:filename,sha256,evidenceId,retainedExport}} function frontmatter(value){const match=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(value);assert.ok(match);const doc=parseDocument(match[1],{uniqueKeys:true,schema:'core'});assert.equal(doc.errors.length,0);return doc.toJS({maxAliasCount:30})} const pluginPath='.codebuddy-plugin/plugin.json',agentPath='agents/senior-project-manager.md',skillPath='skills/minimax-docx/SKILL.md' const plugin=JSON.parse(text(pluginPath)),agent=text(agentPath),skill=text(skillPath) const findings={rootSha256:evidence.rootSha256,metadata:{value:plugin,source:source(pluginPath)},agent:{frontmatter:frontmatter(agent),source:source(agentPath),workspacePrerequisites:['ai/memory-bank/site-setup.md','ai/memory-bank/tasks/[project-slug]-tasklist.md','ai/agents/pm.md','qa-playwright-capture.sh'],sourceBehavior:['Read exact specification; scope matches it','Write 30–60 minute actionable tasks with acceptance criteria','Extract technical stack and reference requirement sections','Word generation/editing routes to bundled minimax-docx']},skill:{frontmatter:frontmatter(skill),source:source(skillPath),pipelines:['A CREATE','B FILL-EDIT','C FORMAT-APPLY (OVERLAY or BASE-REPLACE)'],setup:['bash scripts/setup.sh','powershell scripts/setup.ps1','scripts/env_check.sh'],cli:'dotnet run --project scripts/dotnet/MiniMaxAIDocx.Cli --'},projects:[],scriptFindings:[],coverage:evidence.coverage} for(const file of evidence.files.filter(file=>/\.(?:csproj|slnx)$/.test(file.path))){const value=text(file.path);findings.projects.push({source:source(file.path),targetFramework:/([^<]+)/.exec(value)?.[1],packages:[...value.matchAll(/({name:match[1],version:match[2]})),projectReferences:[...value.matchAll(/match[1])})} for(const file of evidence.files.filter(file=>/\.(?:sh|ps1)$/.test(file.path))){const value=text(file.path),lines=value.split(/\r?\n/);findings.scriptFindings.push({source:source(file.path),lines:lines.map((text,index)=>({line:index+1,text})).filter(({text})=>/dotnet|pandoc|soffice|libreoffice|python|pip |pip3|lxml|defused|apt|brew|winget|curl|https?:\/\/|api[_-]?key|token|node|npm|DOTNET_ROOT|PATH|System\.Drawing/i.test(text)).slice(0,90)})} const cli='skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Cli/Program.cs',cliBody=text(cli) if(cliBody)findings.cli={source:source(cli),dispatch:cliBody,runScriptDeclared:/case\s+"run-script"|"run-script"\s*=>/.test(cliBody)} fs.writeFileSync('.tmp/rea-project-manager-analysis-20261016.json',JSON.stringify(findings,null,2)+'\n') console.log(JSON.stringify({status:evidence.coverage.pending.length?'PARTIAL':'PASS',auditedFiles:evidence.files.length,projects:findings.projects,scriptCount:findings.scriptFindings.length,report:'.tmp/rea-project-manager-analysis-20261016.json'}))