claude-code-session-manager 0.87.0 → 0.88.1
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/README.md +26 -53
- package/dist/assets/{AgentLibrary-DyLWzZDf.js → AgentLibrary-kQF8_wAw.js} +1 -1
- package/dist/assets/{DataModel--mISIJ6h.js → DataModel-CY_mMnsr.js} +1 -1
- package/dist/assets/{History-C2ahUXTg.js → History-Sji2brb0.js} +1 -1
- package/dist/assets/{Hooks-BiC6oyR2.js → Hooks-CtqpO-p5.js} +1 -1
- package/dist/assets/{HostBilko-BPleEOld.js → HostBilko-DN0ydOCr.js} +1 -1
- package/dist/assets/{Library-Dc8Qst1R.js → Library-CoiLZTKh.js} +1 -1
- package/dist/assets/{ListDetail-DIXh-OLX.js → ListDetail-CmqiQ_io.js} +1 -1
- package/dist/assets/{MarkdownEditor-C90bkLXK.js → MarkdownEditor-HPoNeKhT.js} +1 -1
- package/dist/assets/{McpServers-DqcbLOLZ.js → McpServers-Bj1X3_NT.js} +1 -1
- package/dist/assets/{Memory-CW62MXlh.js → Memory-1PKjsM3b.js} +1 -1
- package/dist/assets/{Panel-Bw1FhRuF.js → Panel-I1s6ghPo.js} +1 -1
- package/dist/assets/{Permissions-BcUC-5y8.js → Permissions-BhiiZjHQ.js} +1 -1
- package/dist/assets/{Plugins-BnKx9flD.js → Plugins-gv3_fkPX.js} +2 -2
- package/dist/assets/{ProvenanceBadge-Bw5vNVPT.js → ProvenanceBadge-BGcgBd8V.js} +1 -1
- package/dist/assets/{SaveBar-CWr0O_w-.js → SaveBar-BGr9eZ4g.js} +1 -1
- package/dist/assets/{Scheduler-DYdLuUqq.js → Scheduler-Bdo_awPq.js} +7 -7
- package/dist/assets/{ScopeSwitcher-CrBLbg8s.js → ScopeSwitcher-ukl0qWaA.js} +1 -1
- package/dist/assets/{Settings-DluB-vN1.js → Settings-DJkFj22G.js} +1 -1
- package/dist/assets/{SkillReferenceGraph-CHLSseay.js → SkillReferenceGraph-0t1Qblp6.js} +1 -1
- package/dist/assets/{Skills-gNdo_HNK.js → Skills-CeVdBGE-.js} +1 -1
- package/dist/assets/{SystemPrompt-Cru05-Ia.js → SystemPrompt-CfKvNHi3.js} +1 -1
- package/dist/assets/{TagLibrary-DNHY0xou.js → TagLibrary-DAzNaUPd.js} +1 -1
- package/dist/assets/{TiptapBody-I4lmbCgP.js → TiptapBody--S_rGXoA.js} +1 -1
- package/dist/assets/{Toggle-bWMHjmRh.js → Toggle-Dszm0xnp.js} +1 -1
- package/dist/assets/{index-DV3PorRY.css → index-BHTX4OTc.css} +1 -1
- package/dist/assets/{index-fc_JjdxL.js → index-Dp4Rc--q.js} +356 -356
- package/dist/assets/{settingsSchema-BfhtZnGD.js → settingsSchema-BLbssMYo.js} +1 -1
- package/dist/assets/{whisperWorker-Dbia1OpC.js → whisperWorker-C7ZGQwKg.js} +7 -7
- package/dist/index.html +2 -2
- package/dist/vad/ort-wasm-simd-threaded.asyncify.mjs +106 -110
- package/dist/vad/ort-wasm-simd-threaded.asyncify.wasm +0 -0
- package/dist/vad/ort-wasm-simd-threaded.jsep.mjs +98 -98
- package/dist/vad/ort-wasm-simd-threaded.jsep.wasm +0 -0
- package/dist/vad/ort-wasm-simd-threaded.jspi.mjs +99 -102
- package/dist/vad/ort-wasm-simd-threaded.jspi.wasm +0 -0
- package/dist/vad/ort-wasm-simd-threaded.mjs +46 -46
- package/dist/vad/ort-wasm-simd-threaded.wasm +0 -0
- package/package.json +10 -13
- package/scripts/README.md +59 -0
- package/scripts/audit-ops-hygiene.cjs +350 -0
- package/scripts/hooks/guard-destructive-git.cjs +10 -34
- package/scripts/hooks/guard-inline-implementation.cjs +14 -8
- package/scripts/hooks/guard-prd-writes.cjs +7 -36
- package/scripts/hooks/guard-self-schedule.cjs +175 -0
- package/scripts/ops-sweep.cjs +355 -0
- package/scripts/scheduler-mcp-server.cjs +28 -71
- package/src/main/__tests__/bilkoHost-integration.test.cjs +3 -3
- package/src/main/__tests__/chat-cancel-terminal.test.cjs +6 -9
- package/src/main/__tests__/chat-exit-close-race.test.cjs +3 -3
- package/src/main/__tests__/chat-mcp-consent-notice.test.cjs +4 -5
- package/src/main/__tests__/chat-queue.test.cjs +2 -2
- package/src/main/__tests__/chat-stop-signal.test.cjs +2 -2
- package/src/main/__tests__/dep-orphan-archive-health.test.cjs +77 -0
- package/src/main/__tests__/dod-batchkey.test.cjs +2 -2
- package/src/main/__tests__/dod-drain-hook.test.cjs +2 -2
- package/src/main/__tests__/dod-report.test.cjs +2 -2
- package/src/main/__tests__/dod-reverify.test.cjs +2 -2
- package/src/main/__tests__/epicMint.test.cjs +2 -2
- package/src/main/__tests__/exchanges.test.cjs +2 -2
- package/src/main/__tests__/extractJson.test.cjs +2 -2
- package/src/main/__tests__/files-reject-credentials.test.cjs +1 -1
- package/src/main/__tests__/fixtures/1218-fo-01-move-scripts-lib-into-src-main-lib.log +556 -0
- package/src/main/__tests__/health-build-freshness.test.cjs +39 -0
- package/src/main/__tests__/health-delegation-chain.test.cjs +15 -1
- package/src/main/__tests__/health-queue-dispatch.test.cjs +58 -7
- package/src/main/__tests__/health-tick-liveness.test.cjs +27 -3
- package/src/main/__tests__/health-usage-poller.test.cjs +70 -23
- package/src/main/__tests__/historyRollup.test.cjs +2 -2
- package/src/main/__tests__/kg-augment.test.cjs +2 -2
- package/src/main/__tests__/mcpStatus.test.cjs +2 -2
- package/src/main/__tests__/memoryAggregate.test.cjs +1 -1
- package/src/main/__tests__/memoryStale.test.cjs +1 -1
- package/src/main/__tests__/opsErrorLogTelemetryTap.test.cjs +25 -1
- package/src/main/__tests__/pollLoop-dispatch-on-failure.test.cjs +33 -3
- package/src/main/__tests__/prd-group-allocator.test.cjs +2 -2
- package/src/main/__tests__/prdAdminRouteParity.test.cjs +2 -0
- package/src/main/__tests__/prdAdminRoutes.test.cjs +14 -2
- package/src/main/__tests__/prdAuthoringSeed.test.cjs +39 -0
- package/src/main/__tests__/prdLocationsArchived.test.cjs +20 -13
- package/src/main/__tests__/proc-role-env.test.cjs +125 -0
- package/src/main/__tests__/procname-claude-spawn-sites.test.cjs +304 -0
- package/src/main/__tests__/procname-sm-processes.test.cjs +127 -0
- package/src/main/__tests__/projectHomeAdminRoutes.test.cjs +81 -401
- package/src/main/__tests__/projectPages.test.cjs +63 -149
- package/src/main/__tests__/queue-health-verdict.test.cjs +9 -9
- package/src/main/__tests__/queue-starvation-dispatch-driver.test.cjs +117 -20
- package/src/main/__tests__/queueHistory.test.cjs +2 -2
- package/src/main/__tests__/rateLimitPollerStreak.test.cjs +38 -3
- package/src/main/__tests__/runVerify-landed-commit-outranks.test.cjs +181 -0
- package/src/main/__tests__/runVerify.test.cjs +5 -5
- package/src/main/__tests__/scheduleJobStatusDrift.test.cjs +3 -3
- package/src/main/__tests__/scheduleJobTransitions.test.cjs +2 -2
- package/src/main/__tests__/scheduler-adopted-run-supervision.test.cjs +143 -0
- package/src/main/__tests__/scheduler-autofix-select.test.cjs +2 -2
- package/src/main/__tests__/scheduler-autopromote.test.cjs +2 -2
- package/src/main/__tests__/scheduler-bash-timeout-env.test.cjs +3 -5
- package/src/main/__tests__/scheduler-boot-orphans.test.cjs +78 -97
- package/src/main/__tests__/scheduler-default-eligible-heal.test.cjs +161 -0
- package/src/main/__tests__/scheduler-dispatch-loop.test.cjs +58 -0
- package/src/main/__tests__/scheduler-epic-digest.test.cjs +3 -5
- package/src/main/__tests__/scheduler-force-tick-outcome.test.cjs +2 -2
- package/src/main/__tests__/scheduler-gate-shadow.test.cjs +119 -0
- package/src/main/__tests__/scheduler-guard-verdict-autoresolve.test.cjs +46 -0
- package/src/main/__tests__/scheduler-heartbeat-payload.test.cjs +80 -0
- package/src/main/__tests__/scheduler-inplace-salvage.test.cjs +25 -18
- package/src/main/__tests__/scheduler-investigation-prompt.test.cjs +4 -4
- package/src/main/__tests__/scheduler-launch-failure.test.cjs +3 -5
- package/src/main/__tests__/scheduler-looks-done.test.cjs +26 -7
- package/src/main/__tests__/scheduler-manual-pause.test.cjs +118 -0
- package/src/main/__tests__/scheduler-meta-code-sha.test.cjs +26 -3
- package/src/main/__tests__/scheduler-prd-missing-skip.test.cjs +17 -2
- package/src/main/__tests__/scheduler-prd-persona-spawn.test.cjs +3 -5
- package/src/main/__tests__/scheduler-quiet-machine-lease.test.cjs +41 -6
- package/src/main/__tests__/scheduler-rate-limit-pause.test.cjs +62 -6
- package/src/main/__tests__/scheduler-rate-limit-spin-guard.test.cjs +3 -5
- package/src/main/__tests__/scheduler-reap-dead-running-jobs.test.cjs +23 -4
- package/src/main/__tests__/scheduler-reconcile-cwd-preserve.test.cjs +100 -0
- package/src/main/__tests__/scheduler-reconcile-invalid-repair.test.cjs +3 -3
- package/src/main/__tests__/scheduler-reconcile-quarantine.test.cjs +4 -4
- package/src/main/__tests__/scheduler-shard-quarantine.test.cjs +110 -0
- package/src/main/__tests__/scheduler-shared-tree-guard.test.cjs +81 -1
- package/src/main/__tests__/scheduler-stall-per-project.test.cjs +14 -0
- package/src/main/__tests__/scheduler-starve-escalation.test.cjs +4 -4
- package/src/main/__tests__/scheduler-stranded-autofix-park.test.cjs +245 -0
- package/src/main/__tests__/scheduler-supervisor-record.test.cjs +81 -0
- package/src/main/__tests__/scheduler-tick-cancel-token.test.cjs +2 -2
- package/src/main/__tests__/scheduler-tick-wedge.test.cjs +172 -0
- package/src/main/__tests__/scheduler-transient-failure.test.cjs +2 -2
- package/src/main/__tests__/scheduler-worktree-cap-defer.test.cjs +37 -11
- package/src/main/__tests__/scheduler-worktree-exec-cwd.test.cjs +3 -5
- package/src/main/__tests__/usageSingleFlight.test.cjs +157 -0
- package/src/main/__tests__/workTypeLibrary.test.cjs +1 -1
- package/src/main/bilkoHost.cjs +16 -7
- package/src/main/build-info.json +8 -0
- package/src/main/chatRunner.cjs +4 -2
- package/src/main/config.cjs +2 -3
- package/src/main/docEdit.cjs +4 -2
- package/src/main/health.cjs +276 -52
- package/src/main/heapSnapshot.cjs +2 -2
- package/src/main/historyAggregator.cjs +1 -1
- package/src/main/index.cjs +61 -10
- package/src/main/ipcSchemas.cjs +6 -17
- package/src/main/lib/__tests__/auditLog.test.cjs +38 -0
- package/src/main/lib/__tests__/buildIdentity.test.cjs +121 -0
- package/src/main/lib/__tests__/cwdClassify.test.cjs +111 -0
- package/src/main/lib/__tests__/definitionOfDoneSequence.test.cjs +95 -0
- package/src/main/lib/__tests__/delegationReadiness.test.cjs +1 -1
- package/src/main/lib/__tests__/dispatchLoop.test.cjs +63 -0
- package/src/main/lib/__tests__/gateFixtures.json +20 -0
- package/src/main/lib/__tests__/gitWorktree.test.cjs +8 -1
- package/src/main/lib/__tests__/instanceLock.test.cjs +93 -7
- package/src/main/lib/__tests__/jobSupervisorRecord.test.cjs +78 -0
- package/src/main/lib/__tests__/jobWorktreeBootLive.test.cjs +11 -0
- package/src/main/lib/__tests__/localAdminHttp.test.cjs +1 -1
- package/src/main/lib/__tests__/mcpToolCatalog.test.cjs +6 -1
- package/src/main/lib/__tests__/procIdentity.test.cjs +119 -0
- package/src/main/lib/__tests__/procName.test.cjs +92 -0
- package/src/main/lib/__tests__/queueStoreMachineStateRecovery.test.cjs +67 -0
- package/src/main/lib/__tests__/schedulerMcpServerHelp.test.cjs +6 -7
- package/src/main/lib/__tests__/schedulerMcpServerProjectHome.test.cjs +37 -204
- package/src/main/lib/__tests__/schedulerPaths.test.cjs +226 -0
- package/src/main/lib/__tests__/schedulerPathsWorktree.test.cjs +94 -0
- package/src/main/lib/__tests__/schedulerRuntimeState.test.cjs +56 -0
- package/src/main/lib/__tests__/sessionSlots.test.cjs +45 -0
- package/src/main/lib/__tests__/telemetryBacklog.test.cjs +1 -1
- package/src/main/lib/__tests__/upgradeDrain.test.cjs +130 -0
- package/src/main/lib/__tests__/usageCircuit.test.cjs +61 -0
- package/src/main/lib/__tests__/watchdog-helpers.test.cjs +63 -0
- package/src/main/lib/__tests__/watchdog-relaunch.test.cjs +73 -0
- package/src/main/lib/activeIndexRebuild.cjs +1 -3
- package/src/main/lib/activeSessions.cjs +20 -88
- package/src/main/lib/adoptedRunSupervisor.cjs +136 -0
- package/src/main/lib/agentModelResolve.cjs +33 -1
- package/src/main/lib/agentPersonaSchema.cjs +2 -2
- package/src/main/lib/auditLog.cjs +30 -5
- package/src/main/lib/buildIdentity.cjs +113 -0
- package/src/main/lib/classifyPromptTicket.cjs +3 -2
- package/src/main/lib/claudeBin.cjs +37 -2
- package/src/main/lib/cleanEnv.cjs +27 -1
- package/src/main/lib/credentials.cjs +4 -2
- package/src/main/lib/cwdClassify.cjs +185 -0
- package/src/main/lib/definitionOfDone.cjs +296 -52
- package/src/main/lib/dispatchLoop.cjs +40 -0
- package/src/main/lib/effectiveModelInfo.cjs +9 -10
- package/src/main/lib/ephemeralCwd.cjs +7 -28
- package/src/main/lib/gitWorktree.cjs +95 -8
- package/src/main/lib/guardShims.cjs +3 -3
- package/src/main/lib/historyRollup.cjs +6 -7
- package/src/main/lib/instanceLock.cjs +32 -5
- package/src/main/lib/jobSupervisorRecord.cjs +147 -0
- package/src/main/lib/jobWorktreeBootLive.cjs +9 -5
- package/src/main/lib/localAdminHttp.cjs +9 -27
- package/src/main/lib/mcpToolCatalog.cjs +29 -77
- package/src/main/lib/opsOwnership.cjs +27 -19
- package/src/main/lib/prdAuthoringSeed.cjs +36 -0
- package/src/main/lib/prdLocations.cjs +48 -1
- package/src/main/lib/procIdentity.cjs +126 -0
- package/src/main/lib/procName.cjs +98 -0
- package/src/main/lib/projectHomeAdminRoutes.cjs +56 -327
- package/src/main/lib/queueHistory.cjs +8 -7
- package/src/main/lib/queueStore.cjs +57 -37
- package/src/main/lib/quietMachineLease.cjs +19 -2
- package/src/main/lib/reservationExpiry.cjs +30 -0
- package/src/main/lib/runClaudeP.cjs +4 -2
- package/src/main/lib/runLogRetention.cjs +3 -2
- package/src/main/lib/scheduleJobSchema.cjs +2 -2
- package/src/main/lib/scheduleJobTransitions.cjs +29 -2
- package/src/main/lib/schedulerBatch.cjs +27 -2
- package/src/main/lib/schedulerPaths.cjs +175 -0
- package/src/main/lib/schedulerRuntimeState.cjs +59 -0
- package/src/main/lib/sessionSlots.cjs +47 -9
- package/src/main/lib/smProcNames.cjs +51 -0
- package/src/main/lib/upgradeDrain.cjs +188 -0
- package/src/main/lib/usageCircuit.cjs +53 -6
- package/src/main/lib/watchdogHelpers.cjs +70 -37
- package/src/main/lib/withTimeout.cjs +33 -0
- package/src/main/mcpStatus.cjs +4 -2
- package/src/main/pluginInstall.cjs +6 -2
- package/src/main/projectPages.cjs +41 -145
- package/src/main/pty.cjs +8 -1
- package/src/main/queueOps.cjs +10 -10
- package/src/main/runVerify.cjs +69 -3
- package/src/main/scheduler.cjs +1607 -383
- package/src/main/seedAgentPersonas.cjs +1 -1
- package/src/main/seedDevPlugin.cjs +1 -1
- package/src/main/seedSchedulerMcp.cjs +7 -6
- package/src/main/seedStatus.cjs +1 -1
- package/src/main/supervisor.cjs +5 -3
- package/src/main/usage.cjs +126 -62
- package/src/preload/api.d.ts +18 -64
- package/src/preload/index.cjs +2 -4
- package/src/seed/agents/project-home-builder.md +31 -48
- package/screenshots/.gitkeep +0 -0
- package/screenshots/README-screenshots.md +0 -13
- package/src/main/lib/projectPageSummarySchema.cjs +0 -181
- package/src/main/teams.cjs +0 -95
- package/src/main/templates/project-pages-catalog.json +0 -741
- package/src/main/templates/project-pages-default-home.html +0 -123
- package/src/main/templates/project-pages-pipeline.md +0 -417
- package/src/seed/prompts/code-review/ac-coverage-check.md +0 -8
- package/src/seed/prompts/code-review/correctness-only.md +0 -8
- package/src/seed/prompts/code-review/full-spectrum-high.md +0 -8
- package/src/seed/prompts/code-review/hallucination-check.md +0 -8
- package/src/seed/prompts/code-review/public-api-compat.md +0 -8
- package/src/seed/prompts/code-review/readability-naming.md +0 -8
- package/src/seed/prompts/debugging/bug-as-failing-test.md +0 -8
- package/src/seed/prompts/debugging/git-bisect-regression.md +0 -8
- package/src/seed/prompts/debugging/instrument-intermittent-bug.md +0 -8
- package/src/seed/prompts/debugging/localize-pipeline-failure.md +0 -8
- package/src/seed/prompts/debugging/reproduce-then-diagnose.md +0 -8
- package/src/seed/prompts/documentation/adr-from-change.md +0 -8
- package/src/seed/prompts/documentation/module-readme.md +0 -8
- package/src/seed/prompts/documentation/onboarding-plan.md +0 -8
- package/src/seed/prompts/documentation/refresh-claude-md.md +0 -8
- package/src/seed/prompts/documentation/tsdoc-public-exports.md +0 -8
- package/src/seed/prompts/git-pr/conventional-commit.md +0 -8
- package/src/seed/prompts/git-pr/draft-pr-title-body.md +0 -8
- package/src/seed/prompts/git-pr/pre-commit-safety-sweep.md +0 -8
- package/src/seed/prompts/git-pr/release-notes-block.md +0 -8
- package/src/seed/prompts/git-pr/split-large-pr.md +0 -8
- package/src/seed/prompts/performance/bundle-startup-audit.md +0 -8
- package/src/seed/prompts/performance/complexity-audit.md +0 -8
- package/src/seed/prompts/performance/cpu-profile-hot-path.md +0 -8
- package/src/seed/prompts/performance/db-query-plan-review.md +0 -8
- package/src/seed/prompts/performance/memory-leak-hunt.md +0 -8
- package/src/seed/prompts/qa/api-contract-tests.md +0 -8
- package/src/seed/prompts/qa/e2e-critical-path.md +0 -8
- package/src/seed/prompts/qa/failing-test-for-bug.md +0 -8
- package/src/seed/prompts/qa/find-missing-test-coverage.md +0 -8
- package/src/seed/prompts/qa/stabilize-flaky-test.md +0 -8
- package/src/seed/prompts/qa/tdd-red-first.md +0 -8
- package/src/seed/prompts/qa/visual-regression-review.md +0 -8
- package/src/seed/prompts/qa/wcag-axe-scan.md +0 -8
- package/src/seed/prompts/refactoring/dead-code-sweep.md +0 -8
- package/src/seed/prompts/refactoring/extract-duplicated-pattern.md +0 -8
- package/src/seed/prompts/refactoring/modernize-legacy-file.md +0 -8
- package/src/seed/prompts/refactoring/reduce-cyclomatic-complexity.md +0 -8
- package/src/seed/prompts/refactoring/tighten-module-boundaries.md +0 -8
- package/src/seed/prompts/security/authz-audit.md +0 -8
- package/src/seed/prompts/security/crypto-correctness.md +0 -8
- package/src/seed/prompts/security/cwe-top-25-hunt.md +0 -8
- package/src/seed/prompts/security/dependency-audit.md +0 -8
- package/src/seed/prompts/security/ipc-boundary-hardening.md +0 -8
- package/src/seed/prompts/security/owasp-top-10-staged-diff.md +0 -8
- package/src/seed/prompts/security/secret-credential-scan.md +0 -8
- package/web/README.md +0 -41
- package/web/project-pages/logic/dist/logic.cjs +0 -4709
- package/web/project-pages/render.cjs +0 -70
- package/web/project-pages/renderer/dist/renderer.cjs +0 -18900
- package/web/project-pages/validate-summary.cjs +0 -62
|
@@ -1,27 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* projectPages.cjs — read-only backend for Project Home
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* (
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* creates an empty directory only), matching the corrected "not an
|
|
11
|
-
* OWNERS namespace" storage/ownership note in
|
|
12
|
-
* session-manager-operations/architecture/project-pages-pipeline.md and
|
|
13
|
-
* session-manager-operations/project-pages/README.md. Structure mirrors
|
|
14
|
-
* projectBrief.cjs's `get()`: validatePath first, config.cjs read helpers,
|
|
15
|
-
* one ipcMain.handle registered from index.cjs's registerXHandlers() pattern.
|
|
16
|
-
*
|
|
17
|
-
* Shipped default (PRD "project-home-hosted-html-spec"): when a project has
|
|
18
|
-
* never generated its own output, `get()` no longer returns the bare
|
|
19
|
-
* `{ output: null }` empty-state signal — it falls back to a build-time
|
|
20
|
-
* default `home.html` shipped with the app (`templates/`), returned with
|
|
21
|
-
* `isDefault: true` and `generatedAt: null` so the renderer can label
|
|
22
|
-
* provenance. That default is read from a fixed app-relative path, never
|
|
23
|
-
* written into any project's own `session-manager-operations/` tree — this
|
|
24
|
-
* module stays read-only.
|
|
4
|
+
* projectPages.cjs — read-only backend for Project Home. The whole feature is
|
|
5
|
+
* ONE self-contained HTML file, `session-manager-operations/project-pages/
|
|
6
|
+
* home.html`, written by the `project_home_write` admin route
|
|
7
|
+
* (lib/projectHomeAdminRoutes.cjs). This module only reads it: get() plus a
|
|
8
|
+
* refcounted per-cwd watcher that pushes `project-pages:changed`. It never
|
|
9
|
+
* writes content (watch()'s mkdir creates an empty directory only).
|
|
25
10
|
*/
|
|
26
11
|
|
|
27
12
|
const { ipcMain } = require('electron');
|
|
@@ -37,128 +22,49 @@ function attachWindow(window) {
|
|
|
37
22
|
mainWindow = window;
|
|
38
23
|
}
|
|
39
24
|
|
|
40
|
-
function
|
|
41
|
-
return opsPath(cwd, 'project-pages', '
|
|
25
|
+
function homePath(cwd) {
|
|
26
|
+
return opsPath(cwd, 'project-pages', 'home.html');
|
|
42
27
|
}
|
|
43
28
|
|
|
44
29
|
/**
|
|
45
|
-
* Resolve `cwd`'s
|
|
46
|
-
* throw (a tmpdir/linked-worktree project root
|
|
47
|
-
*
|
|
48
|
-
* propagate. Both get() and the watcher below go through this so a builder
|
|
49
|
-
* Epic running in a worktree can never crash either path.
|
|
30
|
+
* Resolve `cwd`'s home.html path, treating the opsOwnership "ephemeral cwd"
|
|
31
|
+
* throw (a tmpdir/linked-worktree project root) as "no path available"
|
|
32
|
+
* rather than letting it propagate.
|
|
50
33
|
*/
|
|
51
|
-
function
|
|
34
|
+
function tryHomePath(realCwd) {
|
|
52
35
|
try {
|
|
53
|
-
return {
|
|
36
|
+
return { file: homePath(realCwd), ephemeral: false };
|
|
54
37
|
} catch (e) {
|
|
55
|
-
if (e.ephemeral) return {
|
|
38
|
+
if (e.ephemeral) return { file: null, ephemeral: true };
|
|
56
39
|
throw e;
|
|
57
40
|
}
|
|
58
41
|
}
|
|
59
42
|
|
|
60
|
-
|
|
61
|
-
// default-document requirement) — a fixed app-relative path with no
|
|
62
|
-
// user-controlled segment, so it deliberately does NOT go through
|
|
63
|
-
// config.cjs's validatePath (whose allowedRoots is the user's home dir and
|
|
64
|
-
// would reject/mis-resolve a path under the app's own install directory,
|
|
65
|
-
// e.g. when installed via npx/global npm outside $HOME). Read once and
|
|
66
|
-
// cached in-process; this file never changes at runtime.
|
|
67
|
-
const DEFAULT_HOME_PATH = path.join(__dirname, 'templates', 'project-pages-default-home.html');
|
|
68
|
-
let cachedDefaultHomeHtml = null;
|
|
69
|
-
function readDefaultHomeHtml() {
|
|
70
|
-
if (cachedDefaultHomeHtml === null) {
|
|
71
|
-
cachedDefaultHomeHtml = fs.readFileSync(DEFAULT_HOME_PATH, 'utf8');
|
|
72
|
-
}
|
|
73
|
-
return cachedDefaultHomeHtml;
|
|
74
|
-
}
|
|
75
|
-
function defaultOutput() {
|
|
76
|
-
return { home: readDefaultHomeHtml(), generatedAt: null, isDefault: true };
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// The original 4 lenses stay required — their absence still means "no
|
|
80
|
-
// Project Pages generated yet" (now the shipped-default fallback rather
|
|
81
|
-
// than a bare null). 'brief' was added later (5th lens): a project that
|
|
82
|
-
// generated its output BEFORE 'brief'
|
|
83
|
-
// existed has home/marketing/feature/architecture.html but no brief.html, and
|
|
84
|
-
// that must keep reading as "has output" rather than suddenly regressing to
|
|
85
|
-
// the empty state for every pre-existing project. So brief.html is read
|
|
86
|
-
// tolerantly — present, its text is returned; absent, the field is simply
|
|
87
|
-
// omitted from the payload rather than failing the whole read.
|
|
88
|
-
// Partial-output strategy (see this file's module doc + PRD
|
|
89
|
-
// "project-home-generate-preflight-and-push"): the render route
|
|
90
|
-
// (projectHomeAdminRoutes.cjs's doRender) writes every lens file
|
|
91
|
-
// concurrently and writes manifest.json ONLY AFTER all of them have landed.
|
|
92
|
-
// So manifest.json's existence is already an all-or-nothing commit signal —
|
|
93
|
-
// gating get() on it (below) means a reader can never observe a lens file
|
|
94
|
-
// that arrived without its siblings. No second partial-state representation
|
|
95
|
-
// is needed; this file just relies on that write order.
|
|
96
|
-
const REQUIRED_LENSES = ['home', 'marketing', 'feature', 'architecture'];
|
|
97
|
-
const OPTIONAL_LENSES = ['brief'];
|
|
98
|
-
const LENSES = [...REQUIRED_LENSES, ...OPTIONAL_LENSES];
|
|
99
|
-
|
|
43
|
+
/** -> { html: string|null, mtimeMs: number|null } */
|
|
100
44
|
async function get({ cwd }) {
|
|
101
45
|
const realCwd = config.validatePath(cwd);
|
|
102
|
-
const {
|
|
103
|
-
if (ephemeral) {
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
if (!manifestResult.exists || !manifestResult.data || manifestResult.parseError) {
|
|
108
|
-
return { output: defaultOutput() };
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const htmlResults = await Promise.all(
|
|
112
|
-
LENSES.map((lens) => config.readText(path.join(dir, `${lens}.html`))),
|
|
113
|
-
);
|
|
114
|
-
const byLens = Object.fromEntries(LENSES.map((lens, i) => [lens, htmlResults[i]]));
|
|
115
|
-
if (REQUIRED_LENSES.some((lens) => !byLens[lens].exists)) {
|
|
116
|
-
return { output: defaultOutput() };
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const generatedAt = typeof manifestResult.data.generatedAt === 'string' ? manifestResult.data.generatedAt : null;
|
|
120
|
-
if (!generatedAt) {
|
|
121
|
-
return { output: defaultOutput() };
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const output = {
|
|
125
|
-
home: byLens.home.text,
|
|
126
|
-
marketing: byLens.marketing.text,
|
|
127
|
-
feature: byLens.feature.text,
|
|
128
|
-
architecture: byLens.architecture.text,
|
|
129
|
-
generatedAt,
|
|
130
|
-
isDefault: false,
|
|
131
|
-
};
|
|
132
|
-
if (byLens.brief.exists) {
|
|
133
|
-
output.brief = byLens.brief.text;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return { output };
|
|
46
|
+
const { file, ephemeral } = tryHomePath(realCwd);
|
|
47
|
+
if (ephemeral) return { html: null, mtimeMs: null };
|
|
48
|
+
const res = await config.readText(file);
|
|
49
|
+
if (!res.exists) return { html: null, mtimeMs: null };
|
|
50
|
+
return { html: res.text, mtimeMs: res.mtimeMs };
|
|
137
51
|
}
|
|
138
52
|
|
|
139
|
-
// ─── Push channel
|
|
140
|
-
//
|
|
141
|
-
// project-pages:get above is a one-shot pull, fetched once at mount by
|
|
142
|
-
// ProjectHome.tsx. That leaves a finished (or stuck) builder Epic invisible
|
|
143
|
-
// until the next manual refresh/app restart. This section adds a per-cwd
|
|
144
|
-
// chokidar watcher on the output dir (the same debounced-write library
|
|
145
|
-
// config.cjs already uses for its generic file watcher) that recomputes
|
|
146
|
-
// get() and pushes it to the renderer whenever the dir changes.
|
|
53
|
+
// ─── Push channel ─────────────────────────────────────────────────────────
|
|
147
54
|
//
|
|
148
|
-
//
|
|
149
|
-
//
|
|
150
|
-
//
|
|
151
|
-
//
|
|
55
|
+
// project-pages:get is a one-shot pull; this adds a per-cwd chokidar watcher
|
|
56
|
+
// on the project-pages dir that recomputes get() and pushes it to the
|
|
57
|
+
// renderer when home.html is added/changed/removed. Map<realCwd, { watcher,
|
|
58
|
+
// refCount }> — refcounted so several mounted components watching the same
|
|
59
|
+
// cwd share one chokidar instance.
|
|
152
60
|
const outputWatchers = new Map();
|
|
153
61
|
|
|
154
62
|
/**
|
|
155
|
-
* Watch `cwd`'s
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
* a write landing immediately after the call is never missed in the window
|
|
161
|
-
* before the underlying fs watch handle is actually registered.
|
|
63
|
+
* Watch `cwd`'s home.html. Resolves `{ ok: true }` once watching is live (or
|
|
64
|
+
* already watching), or `{ ok: false, reason: 'ephemeral' | 'invalid-cwd' }`
|
|
65
|
+
* when there is nothing safe to watch — not an error, just "no live updates
|
|
66
|
+
* for this cwd". Waits for chokidar's 'ready' so a write landing right after
|
|
67
|
+
* the call is never missed.
|
|
162
68
|
*/
|
|
163
69
|
async function watchOutput(cwd) {
|
|
164
70
|
let realCwd;
|
|
@@ -174,40 +80,32 @@ async function watchOutput(cwd) {
|
|
|
174
80
|
return { ok: true };
|
|
175
81
|
}
|
|
176
82
|
|
|
177
|
-
const {
|
|
83
|
+
const { file, ephemeral } = tryHomePath(realCwd);
|
|
178
84
|
if (ephemeral) {
|
|
179
85
|
return { ok: false, reason: 'ephemeral' };
|
|
180
86
|
}
|
|
181
|
-
//
|
|
182
|
-
//
|
|
183
|
-
//
|
|
184
|
-
|
|
185
|
-
// EMPTY directory only, no content, so it does not conflict with this
|
|
186
|
-
// module's read-only contract or the single-writer law (opsOwnership.cjs)
|
|
187
|
-
// — it bypasses config.cjs's writer-tracked write path deliberately,
|
|
188
|
-
// exactly like a project-home-builder Epic's own untracked Write-tool
|
|
189
|
-
// calls into this same folder (see opsOwnership.cjs's 'project-pages'
|
|
190
|
-
// entry).
|
|
87
|
+
// Watch the parent dir (chokidar silently misses the first write of a file
|
|
88
|
+
// in a not-yet-existing dir). mkdir creates an EMPTY directory only — no
|
|
89
|
+
// content, so the single-writer law (opsOwnership.cjs) is not involved.
|
|
90
|
+
const dir = path.dirname(file);
|
|
191
91
|
fs.mkdirSync(dir, { recursive: true });
|
|
192
92
|
|
|
193
|
-
const push = async () => {
|
|
93
|
+
const push = async (changedPath) => {
|
|
94
|
+
if (changedPath && path.resolve(changedPath) !== path.resolve(file)) return; // only home.html
|
|
194
95
|
let result;
|
|
195
96
|
try {
|
|
196
97
|
result = await get({ cwd: realCwd });
|
|
197
98
|
} catch {
|
|
198
99
|
return; // best-effort; the renderer keeps its last-known output
|
|
199
100
|
}
|
|
200
|
-
sendIfAlive(mainWindow, 'project-pages:changed', { cwd: realCwd,
|
|
101
|
+
sendIfAlive(mainWindow, 'project-pages:changed', { cwd: realCwd, html: result.html, mtimeMs: result.mtimeMs });
|
|
201
102
|
};
|
|
202
103
|
|
|
203
104
|
const watcher = chokidar.watch(dir, {
|
|
204
105
|
ignoreInitial: true,
|
|
205
106
|
persistent: true,
|
|
206
|
-
|
|
207
|
-
//
|
|
208
|
-
// still fires several fs events in quick succession. awaitWriteFinish
|
|
209
|
-
// (same 50ms/25ms shape config.cjs's generic watcher uses) collapses
|
|
210
|
-
// that burst into one push instead of flapping the UI once per file.
|
|
107
|
+
depth: 0,
|
|
108
|
+
// Same 50ms/25ms shape config.cjs's generic watcher uses.
|
|
211
109
|
awaitWriteFinish: { stabilityThreshold: 50, pollInterval: 25 },
|
|
212
110
|
});
|
|
213
111
|
watcher.on('add', push);
|
|
@@ -264,8 +162,6 @@ module.exports = {
|
|
|
264
162
|
watchOutput,
|
|
265
163
|
unwatchOutput,
|
|
266
164
|
closeAllOutputWatchers,
|
|
267
|
-
DEFAULT_HOME_PATH,
|
|
268
|
-
readDefaultHomeHtml,
|
|
269
165
|
// Test-only introspection of the refcounted watcher map.
|
|
270
166
|
_outputWatchers: outputWatchers,
|
|
271
167
|
};
|
package/src/main/pty.cjs
CHANGED
|
@@ -17,6 +17,7 @@ const path = require('node:path');
|
|
|
17
17
|
const os = require('node:os');
|
|
18
18
|
const fs = require('node:fs');
|
|
19
19
|
const { addAllowedRoot } = require('./config.cjs');
|
|
20
|
+
const { aliasedShellBin } = require('./lib/smProcNames.cjs');
|
|
20
21
|
const { cleanChildEnv, pathWithUserBins } = require('./lib/cleanEnv.cjs');
|
|
21
22
|
const { checkInsideHome } = require('./lib/insideHome.cjs');
|
|
22
23
|
const { sendIfAlive } = require('./lib/sendToRenderer.cjs');
|
|
@@ -187,7 +188,13 @@ class PtyManager {
|
|
|
187
188
|
let proc;
|
|
188
189
|
try {
|
|
189
190
|
// Interactive login shell so aliases / nvm / PATH resolve correctly.
|
|
190
|
-
|
|
191
|
+
// `sm-shell` comm (pn-03) via symlink — node-pty has no argv0 option.
|
|
192
|
+
// ONLY interactive terminal tabs get this alias. supervisor.cjs
|
|
193
|
+
// getChildBashCmdlines matches comm === 'bash' EXACTLY over a scheduler
|
|
194
|
+
// job's descendants; no shell in a job's process tree is ever spawned
|
|
195
|
+
// through here, so that detection is unaffected. Non-bash/zsh shells and
|
|
196
|
+
// any alias failure fall back to the real path.
|
|
197
|
+
proc = pty.spawn(aliasedShellBin(shell), ['-il'], {
|
|
191
198
|
name: 'xterm-256color',
|
|
192
199
|
cols,
|
|
193
200
|
rows,
|
package/src/main/queueOps.cjs
CHANGED
|
@@ -32,18 +32,16 @@
|
|
|
32
32
|
const fs = require('node:fs');
|
|
33
33
|
const fsp = require('node:fs/promises');
|
|
34
34
|
const path = require('node:path');
|
|
35
|
-
const os = require('node:os');
|
|
36
35
|
const { ipcMain } = require('electron');
|
|
37
36
|
const { SCHEDULE_SLUG_RE: SLUG_RE, schemas } = require('./ipcSchemas.cjs');
|
|
38
37
|
const logs = require('./logs.cjs');
|
|
39
38
|
const config = require('./config.cjs');
|
|
40
39
|
const { expandHome } = require('./lib/expandHome.cjs');
|
|
41
40
|
const { HISTORY_RETENTION_MS } = require('./lib/schedulerConfig.cjs');
|
|
41
|
+
const schedulerPaths = require('./lib/schedulerPaths.cjs');
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
const PRDS_ARCHIVE_DIR = path.join(ROOT, 'prds-archived');
|
|
46
|
-
const RETAG_LOG = path.join(ROOT, 'retag-log.jsonl');
|
|
43
|
+
// Lazy: resolved via lib/schedulerPaths.cjs at each use (SM_SCHEDULER_HOME).
|
|
44
|
+
const prdsArchiveDir = () => path.join(schedulerPaths.scheduledPlansRoot(), 'prds-archived');
|
|
47
45
|
|
|
48
46
|
// ────────────────────────────────────────────── lint rules
|
|
49
47
|
|
|
@@ -136,7 +134,7 @@ const { resolvePrdsDirs, resolvePrdWriteDir, listEpicPrdDirs } = require('./lib/
|
|
|
136
134
|
// aggregates both so the linter/archive/retag operations still see every
|
|
137
135
|
// PRD regardless of which dir it currently lives in.
|
|
138
136
|
function candidatePrdsDirs() {
|
|
139
|
-
return [
|
|
137
|
+
return [schedulerPaths.prdsRoot(), ...resolvePrdsDirs()];
|
|
140
138
|
}
|
|
141
139
|
|
|
142
140
|
/**
|
|
@@ -574,9 +572,9 @@ async function retagOne({ slug, parallelGroup, estimateMinutes }) {
|
|
|
574
572
|
async function appendRetagLog(entries) {
|
|
575
573
|
if (entries.length === 0) return;
|
|
576
574
|
try {
|
|
577
|
-
await fsp.mkdir(
|
|
575
|
+
await fsp.mkdir(schedulerPaths.scheduledPlansRoot(), { recursive: true });
|
|
578
576
|
const lines = entries.map((e) => JSON.stringify({ ts: new Date().toISOString(), ...e }) + '\n').join('');
|
|
579
|
-
await fsp.appendFile(
|
|
577
|
+
await fsp.appendFile(path.join(schedulerPaths.scheduledPlansRoot(), 'retag-log.jsonl'), lines);
|
|
580
578
|
} catch (e) {
|
|
581
579
|
logs.writeLine({ level: 'warn', scope: 'queueOps', message: 'retag log append failed', meta: { error: e?.message } });
|
|
582
580
|
}
|
|
@@ -629,9 +627,11 @@ module.exports = {
|
|
|
629
627
|
selectAutoArchivable,
|
|
630
628
|
autoArchiveCompleted,
|
|
631
629
|
retagMany,
|
|
632
|
-
PRDS_DIR,
|
|
633
|
-
PRDS_ARCHIVE_DIR,
|
|
634
630
|
archiveDirForSource,
|
|
635
631
|
candidatePrdsDirs,
|
|
636
632
|
findPrdDir,
|
|
637
633
|
};
|
|
634
|
+
|
|
635
|
+
// Lazy path getters (SM_SCHEDULER_HOME resolved at read, never at require).
|
|
636
|
+
Object.defineProperty(module.exports, 'PRDS_DIR', { get: schedulerPaths.prdsRoot, enumerable: true });
|
|
637
|
+
Object.defineProperty(module.exports, 'PRDS_ARCHIVE_DIR', { get: prdsArchiveDir, enumerable: true });
|
package/src/main/runVerify.cjs
CHANGED
|
@@ -808,9 +808,30 @@ function allDeliverablesAlreadyTracked({ cwd, paths, execImpl = execFileSync, ti
|
|
|
808
808
|
* same slug landed, if any — supplied by the
|
|
809
809
|
* caller (scheduler.cjs). Used by the
|
|
810
810
|
* pass_no_commit_prior_run_verified exemption.
|
|
811
|
+
* @param {string|null} [params.jobLandedCommitThisRun] The commit SHA THIS run's own
|
|
812
|
+
* guard cwd HEAD advanced to (spawnJob's
|
|
813
|
+
* `headAtExit` when it differs from
|
|
814
|
+
* `guardHeadBefore`), or the equivalent
|
|
815
|
+
* already-persisted `job.landedCommit` when
|
|
816
|
+
* re-verifying a stale needs_review row. This
|
|
817
|
+
* is a HEAD delta observed for THIS job's own
|
|
818
|
+
* dispatch — strictly stronger attribution than
|
|
819
|
+
* `committedDuringRun`'s repo-wide window scan —
|
|
820
|
+
* and, unlike the now-deleted `sm-job/<slug>`
|
|
821
|
+
* branch tip, it survives `cleanupWorktree`.
|
|
822
|
+
* Used by the ground-truth-outranks-heuristics
|
|
823
|
+
* rule below. Default null for back-compat.
|
|
824
|
+
* @param {number|null} [params.exitCode] The run's process exit code. The
|
|
825
|
+
* ground-truth-outranks-heuristics rule only
|
|
826
|
+
* ever applies when this is exactly 0 — default
|
|
827
|
+
* null so callers that don't pass it keep
|
|
828
|
+
* today's behavior byte-for-byte.
|
|
811
829
|
* @returns {Promise<{verdict:string, reason:string, downgradeTo:string|null}>}
|
|
812
830
|
*/
|
|
813
|
-
async function verifyRun({
|
|
831
|
+
async function verifyRun({
|
|
832
|
+
runDir, prdPath, queueEntry, allJobs = [], committedDuringRun = false, allowPreSentinelHeal = false,
|
|
833
|
+
ghExecImpl, priorLandedCommit = null, jobLandedCommitThisRun = null, exitCode = null,
|
|
834
|
+
}) {
|
|
814
835
|
const { slug } = queueEntry;
|
|
815
836
|
const logPath = path.join(runDir, `${slug}.log`);
|
|
816
837
|
const verdictsPath = path.join(runDir, `${slug}.verdicts.json`);
|
|
@@ -865,9 +886,22 @@ async function verifyRun({ runDir, prdPath, queueEntry, allJobs = [], committedD
|
|
|
865
886
|
// gitHead()/committedInWindow() both fail closed there. In that case
|
|
866
887
|
// ONLY, fall back to the harness-emitted commit evidence in the
|
|
867
888
|
// transcript, which git itself produced and the model cannot fabricate.
|
|
889
|
+
//
|
|
890
|
+
// jobLandedCommitThisRun (spawnJob's own guardHeadBefore/headAtExit delta,
|
|
891
|
+
// or the equivalent already-persisted job.landedCommit on a re-verify
|
|
892
|
+
// pass) is folded into the SAME commitEvidence signal used everywhere in
|
|
893
|
+
// this function — a HEAD delta observed for THIS job's own dispatch is at
|
|
894
|
+
// least as strong as the repo-wide committedDuringRun window scan, so
|
|
895
|
+
// every exemption below that already trusts commitEvidence (no_verdict_
|
|
896
|
+
// sentinel, pass_no_commit, the PASS+commitEvidence sentinel override)
|
|
897
|
+
// should trust this evidence too, not just the new ground-truth rule.
|
|
868
898
|
const cwdIsGitRepo = isGitRepo(queueEntry?.cwd);
|
|
869
|
-
const commitEvidence = committedDuringRun || (!cwdIsGitRepo && transcriptCommitLanded);
|
|
870
|
-
|
|
899
|
+
const commitEvidence = committedDuringRun || Boolean(jobLandedCommitThisRun) || (!cwdIsGitRepo && transcriptCommitLanded);
|
|
900
|
+
let commitEvidenceSource = null;
|
|
901
|
+
if (!committedDuringRun) {
|
|
902
|
+
if (jobLandedCommitThisRun) commitEvidenceSource = 'jobLandedCommitThisRun';
|
|
903
|
+
else if (commitEvidence) commitEvidenceSource = 'transcript';
|
|
904
|
+
}
|
|
871
905
|
|
|
872
906
|
// ── 3. HALT detection ─────────────────────────────────────────────────
|
|
873
907
|
// Primary: check the final `{"type":"result"}` event's `result` text.
|
|
@@ -990,6 +1024,38 @@ async function verifyRun({ runDir, prdPath, queueEntry, allJobs = [], committedD
|
|
|
990
1024
|
|
|
991
1025
|
// Scan for the SCHEDULER_VERDICT sentinel emitted by the finish protocol.
|
|
992
1026
|
const sentinel = scanSentinel(resultEvent, events);
|
|
1027
|
+
|
|
1028
|
+
// Ground truth outranks heuristics: an exit-0 run that landed a commit
|
|
1029
|
+
// ATTRIBUTABLE TO THIS RUN (spawnJob's own guardHeadBefore/headAtExit
|
|
1030
|
+
// delta, or the repo-wide committedDuringRun window scan) and never
|
|
1031
|
+
// printed an explicit SCHEDULER_VERDICT: FAIL demotes every
|
|
1032
|
+
// transcript_errors/verify_unavailable hit from `issues` to `annotations`
|
|
1033
|
+
// — a tool error the agent already recovered from three calls later, or
|
|
1034
|
+
// an environment probe, says nothing once the work is materially proven
|
|
1035
|
+
// to have landed. Deliberately narrower than the sentinel-override below:
|
|
1036
|
+
// it needs no PASS claim at all, only the ABSENCE of an explicit FAIL, so
|
|
1037
|
+
// it also catches the majority no-sentinel-at-all park class that the
|
|
1038
|
+
// PASS+commitEvidence override (further below) can never reach. Never
|
|
1039
|
+
// demotes pass_no_commit/no_verdict_sentinel/abandoned_background_task —
|
|
1040
|
+
// those are added below this point and are about the ABSENCE of a
|
|
1041
|
+
// sentinel/commit, which this same evidence does not resolve.
|
|
1042
|
+
// (Incident: 1218-fo-01 — a `git apply` "patch does not apply" tool error
|
|
1043
|
+
// at event 179/209 was retried and succeeded 3 events later, the run
|
|
1044
|
+
// landed commit d1edf15, and the row was parked needs_review anyway,
|
|
1045
|
+
// spawning a $3.74 fix-plan investigation into work that needed no fix.)
|
|
1046
|
+
const groundTruthOutranksHeuristics = exitCode === 0 && commitEvidence && sentinel !== 'fail';
|
|
1047
|
+
if (groundTruthOutranksHeuristics) {
|
|
1048
|
+
for (let k = issues.length - 1; k >= 0; k--) {
|
|
1049
|
+
if (issues[k].verdict === 'transcript_errors' || issues[k].verdict === 'verify_unavailable') {
|
|
1050
|
+
annotations.push({
|
|
1051
|
+
verdict: issues[k].verdict,
|
|
1052
|
+
reason: `${issues[k].reason} (demoted: exit 0 + commit landed this run outranks transcript heuristics)`,
|
|
1053
|
+
});
|
|
1054
|
+
issues.splice(k, 1);
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
|
|
993
1059
|
const sentinelFields = sentinel ? { sentinel } : {};
|
|
994
1060
|
const extras = (annotations.length || sentinel)
|
|
995
1061
|
? { ...(annotations.length ? { annotations } : {}), ...sentinelFields }
|