@dzhechkov/harness-core 0.5.3 → 0.6.0

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/src/index.ts CHANGED
@@ -221,6 +221,7 @@ export {
221
221
  resumeMode,
222
222
  decideCheckpointResume,
223
223
  serializeCheckpoint,
224
+ decideCheckpointWrite,
224
225
  parseCheckpointRead,
225
226
  checkpointReadCmd,
226
227
  checkpointAppendCmd,
@@ -236,7 +237,9 @@ export {
236
237
  codeCheckpointPersistAllowed,
237
238
  codeStageResultShapeValid,
238
239
  } from './feature-adr-checkpoints.js';
239
- export type { CheckpointStage, CheckpointEntry, ResumeMode, ResumeDecision, ParsedCheckpointRead, TrainingPairFamily, TrainingPair, TrainingPairEvaluation, TrainingPairProvenance, TrainingPairTruncation } from './feature-adr-checkpoints.js';
240
+ export type { CheckpointStage, CheckpointEntry, ResumeMode, ResumeDecision, ParsedCheckpointRead, TrainingPairFamily, TrainingPair, TrainingPairEvaluation, TrainingPairProvenance, TrainingPairTruncation,
241
+ CheckpointWriteVerdict,
242
+ } from './feature-adr-checkpoints.js';
240
243
  export {
241
244
  DOMAIN_LIFT_EXACT,
242
245
  DOMAIN_LIFT_RELATED,
@@ -516,6 +519,12 @@ export {
516
519
  resolveCoderSpec,
517
520
  coderIsCodex,
518
521
  resolveQeSpec,
522
+ crossFamilyQe,
523
+ decideModeBScope,
524
+ partitionReviewFindings,
525
+ parseHashProbe,
526
+ changedFromHashes,
527
+ changeSetProbeCmd,
519
528
  routingRequested,
520
529
  mergeOpts,
521
530
  DEFAULT_MODELS,
@@ -558,15 +567,48 @@ export {
558
567
  PLAN_GATE_SCRIPT,
559
568
  planCompletenessGateCmd,
560
569
  parsePlanGateVerdict,
570
+ // p16-non-js-portability: the gate-script search chain's operator note (ADR-002/AM-7) and the
571
+ // dzBin absolutization (ADR-003). Named for the same reason as the three above.
572
+ refusalNoteFor,
573
+ normalizeDzBin,
561
574
  // qe-bridge-claude: the bridge's path/slug hygiene reuses these rather than minting a second
562
575
  // definition of "safe" (ADR-001 D5-A).
563
576
  isSafeSlug,
564
577
  hasUnsafePathChars,
565
578
  hasDotDotSegment,
579
+ // qe-scoped-review: the two scoped Codex QE dispatch modes + the LOCKED decline taxonomy. NAMED
580
+ // one by one on purpose — an omission here silently drops the export from the published package
581
+ // while the suite stays green (the ADR-002 Confirmation-1 lesson, re-learnt on 2026-08-21 when a
582
+ // fixed export shipped behind two stale workflow mirrors).
583
+ CODEX_REVIEW_TIMEOUT_SECONDS,
584
+ CODEX_REVIEW_DEFAULT_EFFORT,
585
+ CODEX_TIMEOUT,
586
+ CODEX_QE_SIGNAL_PREFIX,
587
+ CODEX_QE_DECLINE_KINDS,
588
+ SCOPED_QE_MAX_FILES,
589
+ SCOPED_QE_MAX_QUESTIONS,
590
+ SCOPED_QE_MAX_PATH_CHARS,
591
+ SCOPED_QE_MAX_QUESTION_CHARS,
592
+ SCOPED_QE_PROMPT_MAX_CHARS,
593
+ isSafeCodexRef,
594
+ codexReviewCommand,
595
+ codexQeSignalCommand,
596
+ scopedQePrompt,
597
+ parseCodexReviewSignal,
598
+ parseCodexReviewFindings,
599
+ gradeFromReviewFindings,
600
+ classifyCodexQeOutcome,
601
+ codexQeDeclineReason,
602
+ codexDeclineReason,
603
+ parseCodexReviewResult,
566
604
  } from './feature-adr-routing.js';
567
605
  export type {
568
606
  StageOpts,
569
607
  RoutingEnv,
608
+ CrossFamilyQeReport,
609
+ ModeBScopeVerdict,
610
+ PartitionedFindings,
611
+ FileHashSnapshot,
570
612
  UsageSignal,
571
613
  UsageAction,
572
614
  CodeLandingStatus,
@@ -583,6 +625,15 @@ export type {
583
625
  ParsedBaselineCapture,
584
626
  ParsedLandingSignal,
585
627
  PlanGateVerdict,
628
+ PlanGateCmdOpts,
629
+ CodexReviewCommandInput,
630
+ CodexReviewCommandResult,
631
+ ScopedQePromptInput,
632
+ ParsedCodexQeSignal,
633
+ CodexQeFinding,
634
+ ClassifyCodexQeInput,
635
+ CodexQeDeclineDetail,
636
+ CodexReviewResult,
586
637
  } from './feature-adr-routing.js';
587
638
  export {
588
639
  CLAUDE_USAGE_MODELS,
@@ -43,11 +43,11 @@ export const BLOBS: Record<string, LoopBlob> = {
43
43
  "checkpoints": {
44
44
  name: "checkpoints",
45
45
  version: "1.1.0",
46
- contentHash: "d4dc6c956be3dd279b225bc5061ec4255babc44ffb5ca58646c9b6ea04a0c8c2",
46
+ contentHash: "a44560c6036fd143b7a3f125fec00fa8b91c3c06ac5b9e1ecfb83d27a5211e9b",
47
47
  sourcePath: "packages/@dzhechkov/harness-core/src/feature-adr-checkpoints.ts",
48
48
  requires: [],
49
- exports: ["CHECKPOINT_STAGES","STAGE_ARTIFACTS","CHECKPOINT_MAX_RESULT_CHARS","CKPT_SCHEMA_VERSION","fnv1a","fnv1a64","checkpointInputHash","resumeMode","decideCheckpointResume","serializeCheckpoint","CHECKPOINT_LS_SENTINEL","parseCheckpointRead","shellQuote","checkpointReadCmd","checkpointAppendCmd","DESIGN_SUBSTAGES","designStageKey","decideDesignFanResume","parseArtifactProbe"],
50
- code: "const CHECKPOINT_STAGES = ['router', 'design', 'plan', 'code', 'qe', 'fleet'];\nconst STAGE_ARTIFACTS = {\n router: null,\n design: '01_requirements.md',\n plan: '06_implementation_plan.md',\n code: '07_code_changes/change_manifest.md',\n qe: '08_qe_report.md',\n fleet: '09_fleet_qe_assessment.md',\n};\nconst CHECKPOINT_MAX_RESULT_CHARS = 12000;\nconst CKPT_SCHEMA_VERSION = 'fa-ckpt-3';\nfunction fnv1a(str) {\n let h = 0x811c9dc5;\n for (let i = 0; i < str.length; i++) {\n h ^= str.charCodeAt(i);\n h = (h + ((h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24))) >>> 0;\n }\n return h.toString(16).padStart(8, '0');\n}\nfunction fnv1a64(str) {\n return fnv1a(str) + fnv1a('fa-ckpt-salt' + str);\n}\nfunction checkpointInputHash(stage, parts) {\n return fnv1a64(JSON.stringify([CKPT_SCHEMA_VERSION, stage, ...parts.map((p) => (p === undefined ? null : p))]));\n}\nfunction resumeMode(raw) {\n return raw === 'never' ? 'never' : raw === 'force' ? 'force' : 'auto';\n}\nconst DESIGN_SUBSTAGES = ['requirements', 'adr', 'qcsd', 'architecture'];\nfunction designStageKey(sub) {\n return 'design:' + sub;\n}\nfunction decideDesignFanResume(opts) {\n const missingSubstages = [];\n opts.required.forEach((sub, i) => {\n const r = opts.results[i];\n if (r === null || r === undefined)\n missingSubstages.push(sub);\n });\n const missingArtifacts = [];\n let probeMissing = false;\n if (opts.artifacts.length > 0) {\n if (opts.postRunListing === null)\n probeMissing = true;\n else\n for (const rel of opts.artifacts)\n if (!opts.postRunListing.has(rel))\n missingArtifacts.push(rel);\n }\n const reason = missingSubstages.length > 0 ? 'substage-missing'\n : probeMissing ? 'probe-not-established'\n : missingArtifacts.length > 0 ? 'artifact-missing'\n : 'ok';\n return { complete: reason === 'ok', missingSubstages, missingArtifacts, reason };\n}\nfunction decideCheckpointResume(opts) {\n if (opts.mode === 'never')\n return { resume: false, reason: 'mode-never' };\n if (!opts.entry || opts.entry.result === null || opts.entry.result === undefined) {\n return { resume: false, reason: 'no-checkpoint' };\n }\n if (opts.entry.inputHash !== opts.inputHash)\n return { resume: false, reason: 'stale-input' };\n if (opts.mode === 'force')\n return { resume: true, reason: 'resumed-force' };\n const required = opts.artifactRel === null ? [] : (typeof opts.artifactRel === 'string' ? [opts.artifactRel] : opts.artifactRel);\n for (const rel of required) {\n if (!opts.listing.has(rel))\n return { resume: false, reason: 'artifact-missing' };\n }\n return { resume: true, reason: 'resumed' };\n}\nfunction serializeCheckpoint(stage, inputHash, result) {\n if (result === null || result === undefined)\n return null;\n let line;\n try {\n line = JSON.stringify({ stage, inputHash, result });\n }\n catch {\n return null;\n }\n if (typeof line !== 'string' || line.length > CHECKPOINT_MAX_RESULT_CHARS)\n return null;\n return line;\n}\nconst CHECKPOINT_LS_SENTINEL = '---FA-CKPT-LS---';\nfunction parseCheckpointRead(text) {\n const out = { entries: {}, listing: new Set(), malformedLines: 0 };\n const raw = String(text ?? '');\n const lines = raw.split('\\n');\n const sentinelAt = lines.findIndex((l) => l.trim() === CHECKPOINT_LS_SENTINEL);\n const body = sentinelAt === -1 ? lines : lines.slice(0, sentinelAt);\n const ls = sentinelAt === -1 ? [] : lines.slice(sentinelAt + 1);\n for (const line of body) {\n const t = line.trim();\n if (t === '')\n continue;\n try {\n const e = JSON.parse(t);\n if (e && typeof e === 'object' && typeof e.stage === 'string' && typeof e.inputHash === 'string' && 'result' in e && e.result !== null && e.result !== undefined) {\n out.entries[e.stage] = e;\n }\n else {\n if (e && typeof e === 'object' && typeof e.stage === 'string')\n delete out.entries[e.stage];\n out.malformedLines++;\n }\n }\n catch {\n out.malformedLines++;\n }\n }\n for (const line of ls) {\n const t = line.trim();\n if (t !== '')\n out.listing.add(t);\n }\n return out;\n}\nfunction shellQuote(s) {\n return \"'\" + String(s).replace(/'/g, \"'\\\\''\") + \"'\";\n}\nfunction checkpointReadCmd(fdirAbs) {\n const q = shellQuote(fdirAbs);\n return ('cat ' + q + '/.fa-state/checkpoints.jsonl 2>/dev/null || true; ' +\n \"echo '\" + CHECKPOINT_LS_SENTINEL + \"'; \" +\n 'cd ' + q + ' 2>/dev/null && find . -maxdepth 2 -type f 2>/dev/null | sed \"s|^\\\\./||\" || true');\n}\nfunction checkpointAppendCmd(fdirAbs, line) {\n const dir = shellQuote(fdirAbs + '/.fa-state');\n const file = shellQuote(fdirAbs + '/.fa-state/checkpoints.jsonl');\n return 'mkdir -p ' + dir + \" && printf '%s\\\\n' \" + shellQuote(line) + ' >> ' + file;\n}\nfunction parseArtifactProbe(opts) {\n if (opts.stdout === null || opts.stdout === undefined)\n return null;\n const known = new Map();\n for (const rel of opts.required)\n known.set('HAVE:' + rel, rel);\n const found = new Set();\n let sentinels = 0;\n for (const raw of String(opts.stdout).split('\\n')) {\n const line = raw.trim();\n if (line === '')\n continue;\n if (line === opts.sentinel) {\n sentinels++;\n continue;\n }\n if (sentinels > 0)\n return null;\n const rel = known.get(line);\n if (rel === undefined)\n return null;\n found.add(rel);\n }\n if (sentinels !== 1)\n return null;\n return found;\n}",
49
+ exports: ["CHECKPOINT_STAGES","STAGE_ARTIFACTS","CHECKPOINT_MAX_RESULT_CHARS","CKPT_SCHEMA_VERSION","fnv1a","fnv1a64","checkpointInputHash","resumeMode","decideCheckpointResume","serializeCheckpoint","CHECKPOINT_LS_SENTINEL","parseCheckpointRead","shellQuote","checkpointReadCmd","checkpointAppendCmd","DESIGN_SUBSTAGES","designStageKey","decideDesignFanResume","parseArtifactProbe","ROUTER_CONTRACT_TOKEN"],
50
+ code: "const CHECKPOINT_STAGES = ['router', 'design', 'plan', 'code', 'qe', 'fleet'];\nconst STAGE_ARTIFACTS = {\n router: '00_complexity_assessment.md',\n design: '01_requirements.md',\n plan: '06_implementation_plan.md',\n code: '07_code_changes/change_manifest.md',\n qe: '08_qe_report.md',\n fleet: '09_fleet_qe_assessment.md',\n};\nconst CHECKPOINT_MAX_RESULT_CHARS = 12000;\nconst CKPT_SCHEMA_VERSION = 'fa-ckpt-3';\nconst ROUTER_CONTRACT_TOKEN = 'router-writes-00-v1';\nfunction fnv1a(str) {\n let h = 0x811c9dc5;\n for (let i = 0; i < str.length; i++) {\n h ^= str.charCodeAt(i);\n h = (h + ((h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24))) >>> 0;\n }\n return h.toString(16).padStart(8, '0');\n}\nfunction fnv1a64(str) {\n return fnv1a(str) + fnv1a('fa-ckpt-salt' + str);\n}\nfunction checkpointInputHash(stage, parts) {\n return fnv1a64(JSON.stringify([CKPT_SCHEMA_VERSION, stage, ...parts.map((p) => (p === undefined ? null : p))]));\n}\nfunction resumeMode(raw) {\n return raw === 'never' ? 'never' : raw === 'force' ? 'force' : 'auto';\n}\nconst DESIGN_SUBSTAGES = ['requirements', 'adr', 'qcsd', 'architecture'];\nfunction designStageKey(sub) {\n return 'design:' + sub;\n}\nfunction decideDesignFanResume(opts) {\n const missingSubstages = [];\n opts.required.forEach((sub, i) => {\n const r = opts.results[i];\n if (r === null || r === undefined)\n missingSubstages.push(sub);\n });\n const missingArtifacts = [];\n let probeMissing = false;\n if (opts.artifacts.length > 0) {\n if (opts.postRunListing === null)\n probeMissing = true;\n else\n for (const rel of opts.artifacts)\n if (!opts.postRunListing.has(rel))\n missingArtifacts.push(rel);\n }\n const reason = missingSubstages.length > 0 ? 'substage-missing'\n : probeMissing ? 'probe-not-established'\n : missingArtifacts.length > 0 ? 'artifact-missing'\n : 'ok';\n return { complete: reason === 'ok', missingSubstages, missingArtifacts, reason };\n}\nfunction decideCheckpointResume(opts) {\n if (opts.mode === 'never')\n return { resume: false, reason: 'mode-never' };\n if (!opts.entry || opts.entry.result === null || opts.entry.result === undefined) {\n return { resume: false, reason: 'no-checkpoint' };\n }\n if (opts.entry.inputHash !== opts.inputHash)\n return { resume: false, reason: 'stale-input' };\n if (opts.mode === 'force')\n return { resume: true, reason: 'resumed-force' };\n const required = opts.artifactRel === null ? [] : (typeof opts.artifactRel === 'string' ? [opts.artifactRel] : opts.artifactRel);\n for (const rel of required) {\n if (!opts.listing.has(rel))\n return { resume: false, reason: 'artifact-missing' };\n }\n return { resume: true, reason: 'resumed' };\n}\nfunction serializeCheckpoint(stage, inputHash, result) {\n if (result === null || result === undefined)\n return null;\n let line;\n try {\n line = JSON.stringify({ stage, inputHash, result });\n }\n catch {\n return null;\n }\n if (typeof line !== 'string' || line.length > CHECKPOINT_MAX_RESULT_CHARS)\n return null;\n return line;\n}\nconst CHECKPOINT_LS_SENTINEL = '---FA-CKPT-LS---';\nfunction parseCheckpointRead(text) {\n const out = { entries: {}, listing: new Set(), malformedLines: 0 };\n const raw = String(text ?? '');\n const lines = raw.split('\\n');\n const sentinelAt = lines.findIndex((l) => l.trim() === CHECKPOINT_LS_SENTINEL);\n const body = sentinelAt === -1 ? lines : lines.slice(0, sentinelAt);\n const ls = sentinelAt === -1 ? [] : lines.slice(sentinelAt + 1);\n for (const line of body) {\n const t = line.trim();\n if (t === '')\n continue;\n try {\n const e = JSON.parse(t);\n if (e && typeof e === 'object' && typeof e.stage === 'string' && typeof e.inputHash === 'string' && 'result' in e && e.result !== null && e.result !== undefined) {\n out.entries[e.stage] = e;\n }\n else {\n if (e && typeof e === 'object' && typeof e.stage === 'string')\n delete out.entries[e.stage];\n out.malformedLines++;\n }\n }\n catch {\n out.malformedLines++;\n }\n }\n for (const line of ls) {\n const t = line.trim();\n if (t !== '')\n out.listing.add(t);\n }\n return out;\n}\nfunction shellQuote(s) {\n return \"'\" + String(s).replace(/'/g, \"'\\\\''\") + \"'\";\n}\nfunction checkpointReadCmd(fdirAbs) {\n const q = shellQuote(fdirAbs);\n return ('cat ' + q + '/.fa-state/checkpoints.jsonl 2>/dev/null || true; ' +\n \"echo '\" + CHECKPOINT_LS_SENTINEL + \"'; \" +\n 'cd ' + q + ' 2>/dev/null && find . -maxdepth 2 -type f 2>/dev/null | sed \"s|^\\\\./||\" || true');\n}\nfunction checkpointAppendCmd(fdirAbs, line) {\n const dir = shellQuote(fdirAbs + '/.fa-state');\n const file = shellQuote(fdirAbs + '/.fa-state/checkpoints.jsonl');\n return 'mkdir -p ' + dir + \" && printf '%s\\\\n' \" + shellQuote(line) + ' >> ' + file;\n}\nfunction parseArtifactProbe(opts) {\n if (opts.stdout === null || opts.stdout === undefined)\n return null;\n const known = new Map();\n for (const rel of opts.required)\n known.set('HAVE:' + rel, rel);\n const found = new Set();\n let sentinels = 0;\n for (const raw of String(opts.stdout).split('\\n')) {\n const line = raw.trim();\n if (line === '')\n continue;\n if (line === opts.sentinel) {\n sentinels++;\n continue;\n }\n if (sentinels > 0)\n return null;\n const rel = known.get(line);\n if (rel === undefined)\n return null;\n found.add(rel);\n }\n if (sentinels !== 1)\n return null;\n return found;\n}",
51
51
  },
52
52
  "training-pairs": {
53
53
  name: "training-pairs",
@@ -79,11 +79,11 @@ export const BLOBS: Record<string, LoopBlob> = {
79
79
  "codex-dispatch": {
80
80
  name: "codex-dispatch",
81
81
  version: "1.0.0",
82
- contentHash: "140da3714d2507683b0a27fcb01fa449ea3cb1619f1a2e181aaf24291397642d",
82
+ contentHash: "f203268da376fa993ce61d38b8fc6a24db4ac1e3edb6b90662f86ae4351a30e7",
83
83
  sourcePath: "packages/@dzhechkov/harness-core/src/feature-adr-routing.ts",
84
84
  requires: [],
85
85
  exports: ["codexDispatchMode","codexExecPlan","needsCodeLandedBarrier","decideCodeLanding"],
86
- code: "const CODE_LANDING_PIPELINE_PREFIXES = ['features/', '.dz/', '.agentic-qe/', 'roam/'];\nfunction codeLandingEmptySignal(seconds) {\n return 'changed=0 after ' + seconds + 's — genuinely not landed';\n}\nfunction needsCodeLandedBarrier(coderUsed) {\n return coderUsed === 'codex' || coderUsed === 'codex-fallback';\n}\nfunction stripCodeLandingPath(path) {\n let p = String(path || '').trim().replace(/\\\\/g, '/');\n while (p.indexOf('./') === 0)\n p = p.slice(2);\n return p.replace(/\\/+/g, '/');\n}\nfunction classifyCodeLandingPathReject(path) {\n const p = stripCodeLandingPath(path);\n if (!p)\n return 'empty-after-strip';\n if (p[0] === '/')\n return 'absolute-path';\n if (p === '..' || p.indexOf('../') === 0 || p.indexOf('/../') >= 0 || p.endsWith('/..'))\n return 'traversal';\n if (/[\\0\\r\\n\\t \"'\\x60$;&|<>*?()[\\]{}!]/.test(p))\n return 'not-a-path';\n if (p.endsWith('/'))\n return 'not-a-path';\n for (const prefix of CODE_LANDING_PIPELINE_PREFIXES) {\n const bare = prefix.slice(0, -1);\n if (p === bare || p.indexOf(prefix) === 0)\n return 'pipeline-artifact-path';\n }\n return null;\n}\nfunction normalizeCodeLandingPath(path) {\n return classifyCodeLandingPathReject(path) === null ? stripCodeLandingPath(path) : '';\n}\nfunction filterPollableCodePaths(paths) {\n const out = [];\n const seen = new Set();\n for (const path of paths || []) {\n const normalized = normalizeCodeLandingPath(path);\n if (!normalized || seen.has(normalized))\n continue;\n seen.add(normalized);\n out.push(normalized);\n }\n return out;\n}\nfunction isNewlyChanged(path, baseline, currentHashes) {\n if (!baseline || !baseline.ok)\n return false;\n let recorded = null;\n for (const entry of baseline.entries) {\n if (entry.path === path) {\n recorded = entry.hash;\n break;\n }\n }\n if (recorded === null)\n return true;\n const now = currentHashes ? currentHashes[path] : undefined;\n if (now === undefined)\n return false;\n return now !== recorded;\n}\nfunction decideCodeLanding(snapshot) {\n const maxWaitMs = Math.max(0, snapshot.maxWaitMs);\n const elapsedMs = Math.max(0, snapshot.elapsedMs);\n const elapsedSeconds = Math.floor(elapsedMs / 1000);\n const expectedPaths = filterPollableCodePaths(snapshot.expectedPaths);\n const changedPaths = filterPollableCodePaths(snapshot.changedEntries.map(function (entry) { return entry.path; }));\n if (expectedPaths.length === 0) {\n return {\n status: 'inconclusive',\n reason: 'empty-plan-block',\n changed: 0,\n elapsedMs: elapsedMs,\n elapsedSeconds: elapsedSeconds,\n expectedPaths: expectedPaths,\n matchedExpectedPaths: [],\n changedPaths: changedPaths,\n predicate: 'no-expected-targets',\n qeSignalLine: 'CODEX-LANDING-SIGNAL status=inconclusive predicate=no-expected-targets reason=empty-plan-block',\n };\n }\n const baseline = snapshot.baseline;\n if (!baseline || !baseline.ok) {\n const reason = baseline && baseline.reason ? baseline.reason : 'no-baseline';\n return {\n status: 'inconclusive',\n reason: reason,\n changed: 0,\n elapsedMs: elapsedMs,\n elapsedSeconds: elapsedSeconds,\n expectedPaths: expectedPaths,\n matchedExpectedPaths: [],\n changedPaths: changedPaths,\n predicate: 'newly-changed',\n qeSignalLine: 'CODEX-LANDING-SIGNAL status=inconclusive predicate=newly-changed reason=' + reason,\n };\n }\n const changed = new Set(changedPaths);\n const matchedExpectedPaths = expectedPaths.filter(function (path) {\n return changed.has(path) && isNewlyChanged(path, baseline, snapshot.currentHashes);\n });\n if (matchedExpectedPaths.length > 0) {\n return {\n status: 'landed',\n changed: matchedExpectedPaths.length,\n elapsedMs: elapsedMs,\n elapsedSeconds: elapsedSeconds,\n expectedPaths: expectedPaths,\n matchedExpectedPaths: matchedExpectedPaths,\n changedPaths: changedPaths,\n predicate: 'newly-changed',\n qeSignalLine: 'CODEX-LANDING-SIGNAL status=landed changed=' +\n matchedExpectedPaths.length +\n ' after=' +\n elapsedSeconds +\n 's predicate=newly-changed matched=' +\n matchedExpectedPaths.join(','),\n };\n }\n if (elapsedMs < maxWaitMs) {\n return {\n status: 'not-yet-flushed',\n changed: 0,\n elapsedMs: elapsedMs,\n elapsedSeconds: elapsedSeconds,\n expectedPaths: expectedPaths,\n matchedExpectedPaths: [],\n changedPaths: changedPaths,\n predicate: 'empty-before-timeout',\n qeSignalLine: 'CODEX-LANDING-SIGNAL status=not-yet-flushed changed=0 after ' + elapsedSeconds + 's — not yet flushed',\n };\n }\n const terminalSeconds = Math.ceil(maxWaitMs / 1000);\n return {\n status: 'genuinely-not-landed',\n changed: 0,\n elapsedMs: elapsedMs,\n elapsedSeconds: terminalSeconds,\n expectedPaths: expectedPaths,\n matchedExpectedPaths: [],\n changedPaths: changedPaths,\n predicate: 'empty-after-timeout',\n qeSignalLine: 'CODEX-LANDING-SIGNAL status=genuinely-not-landed ' + codeLandingEmptySignal(terminalSeconds),\n };\n}\nconst WRAPPER_STAGES = { code: 1, plan: 1 };\nfunction codexDispatchMode(stage) {\n return WRAPPER_STAGES[stage] ? 'wrapper' : 'exec';\n}\nconst CODEX_EXEC_PROMPT_CEILING_CHARS = 24000;\nfunction codexExecPlan(input) {\n if (codexDispatchMode(input.stage) === 'wrapper') {\n return { mode: 'wrapper', reason: 'deliverable is a file written out-of-band' };\n }\n if (!input.probedId) {\n return { mode: 'claude', reason: 'no codex model id answered the probe' };\n }\n if (input.promptChars > CODEX_EXEC_PROMPT_CEILING_CHARS) {\n return {\n mode: 'claude',\n reason: 'prompt is ' +\n input.promptChars +\n ' chars, over the ' +\n CODEX_EXEC_PROMPT_CEILING_CHARS +\n '-char codex exec ceiling (it would stall)',\n };\n }\n return { mode: 'exec', reason: 'codex exec on ' + input.probedId };\n}",
86
+ code: "const CODE_LANDING_PIPELINE_PREFIXES = ['features/', '.dz/', '.agentic-qe/', 'roam/'];\nfunction codeLandingEmptySignal(seconds) {\n return 'changed=0 after ' + seconds + 's — genuinely not landed';\n}\nfunction needsCodeLandedBarrier(coderUsed) {\n return coderUsed === 'codex' || coderUsed === 'codex-fallback';\n}\nfunction stripCodeLandingPath(path) {\n let p = String(path || '').trim().replace(/\\\\/g, '/');\n while (p.indexOf('./') === 0)\n p = p.slice(2);\n return p.replace(/\\/+/g, '/');\n}\nfunction classifyCodeLandingPathReject(path) {\n const p = stripCodeLandingPath(path);\n if (!p)\n return 'empty-after-strip';\n if (p[0] === '/')\n return 'absolute-path';\n if (p === '..' || p.indexOf('../') === 0 || p.indexOf('/../') >= 0 || p.endsWith('/..'))\n return 'traversal';\n if (/[\\0\\r\\n\\t \"'\\x60$;&|<>*?()[\\]{}!]/.test(p))\n return 'not-a-path';\n if (p.endsWith('/'))\n return 'not-a-path';\n for (const prefix of CODE_LANDING_PIPELINE_PREFIXES) {\n const bare = prefix.slice(0, -1);\n if (p === bare || p.indexOf(prefix) === 0)\n return 'pipeline-artifact-path';\n }\n return null;\n}\nfunction normalizeCodeLandingPath(path) {\n return classifyCodeLandingPathReject(path) === null ? stripCodeLandingPath(path) : '';\n}\nfunction filterPollableCodePaths(paths) {\n const out = [];\n const seen = new Set();\n for (const path of paths || []) {\n const normalized = normalizeCodeLandingPath(path);\n if (!normalized || seen.has(normalized))\n continue;\n seen.add(normalized);\n out.push(normalized);\n }\n return out;\n}\nfunction isNewlyChanged(path, baseline, currentHashes) {\n if (!baseline || !baseline.ok)\n return false;\n let recorded = null;\n for (const entry of baseline.entries) {\n if (entry.path === path) {\n recorded = entry.hash;\n break;\n }\n }\n if (recorded === null)\n return true;\n const now = currentHashes ? currentHashes[path] : undefined;\n if (now === undefined)\n return false;\n return now !== recorded;\n}\nfunction decideCodeLanding(snapshot) {\n const maxWaitMs = Math.max(0, snapshot.maxWaitMs);\n const elapsedMs = Math.max(0, snapshot.elapsedMs);\n const elapsedSeconds = Math.floor(elapsedMs / 1000);\n const expectedPaths = filterPollableCodePaths(snapshot.expectedPaths);\n const changedPaths = filterPollableCodePaths(snapshot.changedEntries.map(function (entry) { return entry.path; }));\n if (expectedPaths.length === 0) {\n return {\n status: 'inconclusive',\n reason: 'empty-plan-block',\n changed: 0,\n elapsedMs: elapsedMs,\n elapsedSeconds: elapsedSeconds,\n expectedPaths: expectedPaths,\n matchedExpectedPaths: [],\n changedPaths: changedPaths,\n predicate: 'no-expected-targets',\n qeSignalLine: 'CODEX-LANDING-SIGNAL status=inconclusive predicate=no-expected-targets reason=empty-plan-block',\n };\n }\n const baseline = snapshot.baseline;\n if (!baseline || !baseline.ok) {\n const reason = baseline && baseline.reason ? baseline.reason : 'no-baseline';\n return {\n status: 'inconclusive',\n reason: reason,\n changed: 0,\n elapsedMs: elapsedMs,\n elapsedSeconds: elapsedSeconds,\n expectedPaths: expectedPaths,\n matchedExpectedPaths: [],\n changedPaths: changedPaths,\n predicate: 'newly-changed',\n qeSignalLine: 'CODEX-LANDING-SIGNAL status=inconclusive predicate=newly-changed reason=' + reason,\n };\n }\n const changed = new Set(changedPaths);\n const matchedExpectedPaths = expectedPaths.filter(function (path) {\n return changed.has(path) && isNewlyChanged(path, baseline, snapshot.currentHashes);\n });\n if (matchedExpectedPaths.length > 0) {\n return {\n status: 'landed',\n changed: matchedExpectedPaths.length,\n elapsedMs: elapsedMs,\n elapsedSeconds: elapsedSeconds,\n expectedPaths: expectedPaths,\n matchedExpectedPaths: matchedExpectedPaths,\n changedPaths: changedPaths,\n predicate: 'newly-changed',\n qeSignalLine: 'CODEX-LANDING-SIGNAL status=landed changed=' +\n matchedExpectedPaths.length +\n ' after=' +\n elapsedSeconds +\n 's predicate=newly-changed matched=' +\n matchedExpectedPaths.join(','),\n };\n }\n if (elapsedMs < maxWaitMs) {\n return {\n status: 'not-yet-flushed',\n changed: 0,\n elapsedMs: elapsedMs,\n elapsedSeconds: elapsedSeconds,\n expectedPaths: expectedPaths,\n matchedExpectedPaths: [],\n changedPaths: changedPaths,\n predicate: 'empty-before-timeout',\n qeSignalLine: 'CODEX-LANDING-SIGNAL status=not-yet-flushed changed=0 after ' + elapsedSeconds + 's — not yet flushed',\n };\n }\n const terminalSeconds = Math.ceil(maxWaitMs / 1000);\n return {\n status: 'genuinely-not-landed',\n changed: 0,\n elapsedMs: elapsedMs,\n elapsedSeconds: terminalSeconds,\n expectedPaths: expectedPaths,\n matchedExpectedPaths: [],\n changedPaths: changedPaths,\n predicate: 'empty-after-timeout',\n qeSignalLine: 'CODEX-LANDING-SIGNAL status=genuinely-not-landed ' + codeLandingEmptySignal(terminalSeconds),\n };\n}\nconst WRAPPER_STAGES = { code: 1, plan: 1 };\nfunction codexDispatchMode(stage) {\n return WRAPPER_STAGES[stage] ? 'wrapper' : 'exec';\n}\nconst CODEX_EXEC_PROMPT_CEILING_CHARS = 24000;\nfunction codexExecPlan(input) {\n if (codexDispatchMode(input.stage) === 'wrapper') {\n return { mode: 'wrapper', reason: 'deliverable is a file written out-of-band' };\n }\n if (!input.probedId) {\n return { mode: 'claude', reason: 'no codex model id answered the probe' };\n }\n if (input.stage === 'qe' && input.scoped !== true) {\n return {\n mode: 'claude',\n reason: 'qe prompt is not SCOPED — an unscoped codex exec QE buys reconnaissance, not review ' +\n '(MEASURED 2026-08-21: 19038 chars, 280s, exit 124, no verdict)',\n };\n }\n if (input.promptChars > CODEX_EXEC_PROMPT_CEILING_CHARS) {\n return {\n mode: 'claude',\n reason: 'prompt is ' +\n input.promptChars +\n ' chars, over the ' +\n CODEX_EXEC_PROMPT_CEILING_CHARS +\n '-char codex exec ceiling (it would stall)',\n };\n }\n return { mode: 'exec', reason: 'codex exec on ' + input.probedId };\n}\nconst SCOPED_QE_MAX_FILES = 3;\nconst SCOPED_QE_MAX_QUESTIONS = 4;\nconst SCOPED_QE_MAX_PATH_CHARS = 200;\nconst SCOPED_QE_MAX_QUESTION_CHARS = 200;\nfunction scopedQePrompt(input) {\n const o = input || {};\n const rawFiles = Array.isArray(o.files) ? o.files : [];\n const files = [];\n for (const f of rawFiles) {\n const s = String(f === undefined || f === null ? '' : f).trim();\n if (s === '')\n continue;\n if (files.indexOf(s) !== -1)\n continue;\n files.push(s.slice(0, SCOPED_QE_MAX_PATH_CHARS));\n if (files.length >= SCOPED_QE_MAX_FILES)\n break;\n }\n if (files.length === 0)\n return '';\n const rawQuestions = Array.isArray(o.questions) ? o.questions : [];\n const questions = [];\n for (const q of rawQuestions) {\n const s = String(q === undefined || q === null ? '' : q).trim().replace(/\\s+/g, ' ');\n if (s === '')\n continue;\n questions.push(s.slice(0, SCOPED_QE_MAX_QUESTION_CHARS));\n if (questions.length >= SCOPED_QE_MAX_QUESTIONS)\n break;\n }\n if (questions.length === 0) {\n questions.push('Is this change correct, and does the test named by its ADR actually DISCRIMINATE (would it fail if the protection were deleted)?');\n }\n const slug = String(o.slug === undefined || o.slug === null ? '' : o.slug).trim().slice(0, 60);\n let out = 'Read ONLY these files: ' + files.join(', ') + '. Do NOT open any other file and do NOT explore the repository.';\n if (slug !== '')\n out += ' They are the changed files of feature ' + slug + '.';\n out += '\\n\\nAnswer these ' + questions.length + ' questions about them:\\n';\n for (let i = 0; i < questions.length; i++)\n out += i + 1 + '. ' + questions[i] + '\\n';\n out += '\\nFinish with a single final line: Grade: <A|B|C|D>';\n return out;\n}",
87
87
  },
88
88
  "challenge-panel": {
89
89
  name: "challenge-panel",