@kynver-app/runtime 0.1.47 → 0.1.48

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.
@@ -0,0 +1,8 @@
1
+ export interface HarnessExpertReviewTaskShape {
2
+ title?: string;
3
+ personaSlug?: string | null;
4
+ parentTaskId?: string | null;
5
+ executorRef?: string | null;
6
+ }
7
+ /** Expert review workers must not inherit landing-only PR gates or open new PRs. */
8
+ export declare function isHarnessExpertReviewWorker(worker: HarnessExpertReviewTaskShape): boolean;
package/dist/index.js CHANGED
@@ -2149,6 +2149,7 @@ function buildPrompt(input) {
2149
2149
  "Structured final result (recommended): record completion as JSON with summary, laneExpertise { whatChanged, why, files, prUrls, verification, risks, blockers, lessonsLearned, laneGuidance }, and targetPrReconciliation [{ prUrl, outcome: merged|skipped|blocked, mergeCommit?, reason? }] for every target PR on landing-only tasks.",
2150
2150
  "Completion handoff (required): before you stop, ensure the harness records a final result \u2014 summarize outcome in your last message and append a heartbeat line with phase `complete`. If you leave uncommitted changes or committed work without a PR, the orchestrator blocks completion until a GitHub PR exists (or you discard/commit cleanly). Exiting with only dirty files and no PR routes to salvage review, not production review.",
2151
2151
  "PR-ready handoff: for substantial implementation work, commit, push, and open a GitHub PR (draft OK) on your branch before finishing \u2014 or rely on the harness to run `gh pr create` at completion when `gh` is authenticated.",
2152
+ "Expert review / production-review workers (Dalton/Lorentz, plan-review-task, scheduledJob reviewer children): do NOT open new implementation PRs \u2014 review the parent task's existing PR and record reviewVerdict in finalResult; landing-contract targetPrReconciliation does not apply.",
2152
2153
  "Worker resource guard: do not run full monorepo verification (`npm run typecheck`, `npm run build`, or equivalent) from this worker lane unless an operator explicitly requests it. Use targeted checks for touched paths and rely on CI/operator lanes for heavy gates.",
2153
2154
  "npm publish boundary: do not run `npm publish`, do not republish `@kynver-app/*` packages, and do not block on an operator to publish. When you need newer runtime code than npm, use this repo checkout (`npm run kynver:build`, `npm run kynver`) and record evidence: packages/kynver-runtime/package.json version + git ref in your completion report.",
2154
2155
  "If verification fails (including OOM), append a heartbeat line immediately with the last command, failure reason, dirty-file status, commit/PR handoff state, and next action so recovery does not require log spelunking.",
@@ -2390,6 +2391,32 @@ function completionPostSucceeded(summary) {
2390
2391
  return summary.taskAdvanced;
2391
2392
  }
2392
2393
 
2394
+ // src/harness-expert-review.ts
2395
+ var EXPERT_LANE_REVIEW_REF = "expert-lane-pr-review:";
2396
+ var PLAN_REVIEW_EXECUTOR_REF = "plan-review-task";
2397
+ var SCHEDULED_JOB_EXECUTOR_REF = "scheduledjob:";
2398
+ function normalizePersonaSlug(value) {
2399
+ if (!value) return null;
2400
+ const t = value.trim().toLowerCase();
2401
+ return t.length ? t : null;
2402
+ }
2403
+ function isHarnessExpertReviewWorker(worker) {
2404
+ const ref = (worker.executorRef ?? "").toLowerCase();
2405
+ if (ref.startsWith(EXPERT_LANE_REVIEW_REF)) return true;
2406
+ if (ref === PLAN_REVIEW_EXECUTOR_REF || ref.startsWith("daemon-review:")) return true;
2407
+ if (ref.startsWith(SCHEDULED_JOB_EXECUTOR_REF) && worker.parentTaskId) {
2408
+ const persona = normalizePersonaSlug(worker.personaSlug);
2409
+ if (persona === "lorentz" || persona === "dalton") return true;
2410
+ }
2411
+ const title = (worker.title ?? "").toLowerCase();
2412
+ if (title.includes("expert pr review")) return true;
2413
+ if (worker.parentTaskId && (title.startsWith("review:") || title.includes("review required") || title.includes("runtime review"))) {
2414
+ const persona = normalizePersonaSlug(worker.personaSlug);
2415
+ if (persona === "lorentz" || persona === "dalton") return true;
2416
+ }
2417
+ return false;
2418
+ }
2419
+
2393
2420
  // src/pr-handoff/pr-handoff-assess.ts
2394
2421
  var REVIEW_LANE_RULE = /^(lane:)?(review|deep_review|planning|landing)(:|$)/i;
2395
2422
  function trimOrNull4(value) {
@@ -2420,6 +2447,14 @@ function assessPrHandoffRequirement(input) {
2420
2447
  if (!input.dispatched) {
2421
2448
  return { required: false, reason: "not_dispatched" };
2422
2449
  }
2450
+ if (isHarnessExpertReviewWorker({
2451
+ title: input.taskTitle ?? void 0,
2452
+ personaSlug: input.personaSlug,
2453
+ parentTaskId: input.parentTaskId,
2454
+ executorRef: input.executorRef
2455
+ })) {
2456
+ return { required: false, reason: "expert_review_task" };
2457
+ }
2423
2458
  const rule = trimOrNull4(input.routingRule) ?? "";
2424
2459
  if (rule && REVIEW_LANE_RULE.test(rule)) {
2425
2460
  return { required: false, reason: "review_lane" };
@@ -2427,7 +2462,7 @@ function assessPrHandoffRequirement(input) {
2427
2462
  if (trimOrNull4(input.patchPath) || trimOrNull4(input.artifactBundlePath)) {
2428
2463
  return { required: false, reason: "patch_or_bundle" };
2429
2464
  }
2430
- const prUrl = trimOrNull4(input.prUrl) ?? trimOrNull4(input.snapshot.prUrl);
2465
+ const prUrl = trimOrNull4(input.prUrl) ?? trimOrNull4(input.taskPrUrl) ?? trimOrNull4(input.snapshot.prUrl);
2431
2466
  if (prUrl) {
2432
2467
  return { required: false, reason: "already_has_pr" };
2433
2468
  }
@@ -2644,6 +2679,11 @@ function ensurePrReadyHandoff(input, exec = defaultPrHandoffExec) {
2644
2679
  dispatched: input.worker.dispatched,
2645
2680
  routingRule: input.worker.routingRule,
2646
2681
  prUrl: prUrlHint,
2682
+ taskTitle: input.worker.taskTitle,
2683
+ executorRef: input.worker.executorRef,
2684
+ parentTaskId: input.worker.parentTaskId,
2685
+ personaSlug: input.worker.personaSlug,
2686
+ taskPrUrl: input.worker.taskPrUrl,
2647
2687
  snapshot
2648
2688
  });
2649
2689
  if (!requirement.required) {
@@ -3523,6 +3563,10 @@ function spawnWorkerProcess(run, opts) {
3523
3563
  ...!opts.agentOsId || !opts.taskId ? { localOnly: true } : {},
3524
3564
  routingRule: routing.rule,
3525
3565
  ...routing.requestedModel ? { requestedModel: routing.requestedModel } : {},
3566
+ ...opts.executorRef ? { executorRef: String(opts.executorRef) } : {},
3567
+ ...opts.parentTaskId ? { parentTaskId: String(opts.parentTaskId) } : {},
3568
+ ...opts.taskTitle ? { taskTitle: String(opts.taskTitle) } : {},
3569
+ ...opts.taskPrUrl ? { taskPrUrl: String(opts.taskPrUrl) } : {},
3526
3570
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
3527
3571
  };
3528
3572
  saveWorker(run.id, worker);
@@ -4217,7 +4261,7 @@ function readHarnessWorkerContext(decision) {
4217
4261
  personaInjectionReady
4218
4262
  };
4219
4263
  }
4220
- function normalizePersonaSlug(value) {
4264
+ function normalizePersonaSlug2(value) {
4221
4265
  if (typeof value !== "string") return null;
4222
4266
  const trimmed = value.trim().toLowerCase();
4223
4267
  return trimmed.length ? trimmed : null;
@@ -4348,7 +4392,7 @@ async function dispatchRun(args) {
4348
4392
  const task = decision.task;
4349
4393
  const harnessContext = readHarnessWorkerContext(decision);
4350
4394
  const taskId = String(task.id);
4351
- const expectedPersona = normalizePersonaSlug(task.personaSlug);
4395
+ const expectedPersona = normalizePersonaSlug2(task.personaSlug);
4352
4396
  if (expectedPersona && (!harnessContext?.personaInjectionReady || !harnessContext.personaMarkdown)) {
4353
4397
  outcomes.push({
4354
4398
  taskId,
@@ -4392,6 +4436,10 @@ async function dispatchRun(args) {
4392
4436
  agentOsId,
4393
4437
  taskId: String(task.id),
4394
4438
  planId,
4439
+ executorRef: task.executorRef ? String(task.executorRef) : void 0,
4440
+ parentTaskId: task.parentTaskId ? String(task.parentTaskId) : void 0,
4441
+ taskTitle: task.title ? String(task.title) : void 0,
4442
+ taskPrUrl: task.prUrl ? String(task.prUrl) : void 0,
4395
4443
  instructionPolicyMarkdown: harnessContext?.instructionPolicyMarkdown ?? null,
4396
4444
  instructionPolicyFingerprint: harnessContext?.instructionPolicyFingerprint ?? null,
4397
4445
  instructionPolicyEvidence: harnessContext?.instructionPolicyEvidence ?? null,