@navels/neal 0.1.0 → 0.2.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.
@@ -39,6 +39,54 @@ export function resolvePlanningAdjudicationContext(state) {
39
39
  derivedFromScopeNumber: derivedPlanReview && derivedPlan ? derivedPlan.parentScopeNumber : null,
40
40
  };
41
41
  }
42
+ // Mirrors resolveExecuteReviewDisposition in adjudicator/execute.ts: one resolver derives every
43
+ // disposition-dependent value runPlanReviewPhase persists (plus the transition signal it asserts)
44
+ // from the same condition set, so the five outcomes can never drift apart.
45
+ export function resolvePlanReviewDisposition(args) {
46
+ if (args.shouldBlockForConvergence) {
47
+ return {
48
+ planningSignal: 'block_for_operator',
49
+ phase: 'blocked',
50
+ status: 'blocked',
51
+ derivedPlanStatus: args.currentDerivedPlanStatus,
52
+ blockedFromPhase: 'reviewer_plan',
53
+ };
54
+ }
55
+ if (args.hasBlockingFindings) {
56
+ return {
57
+ planningSignal: args.reachedMaxRounds ? 'block_for_operator' : 'request_revision',
58
+ phase: args.reachedMaxRounds ? 'blocked' : 'coder_plan_response',
59
+ status: args.reachedMaxRounds ? 'blocked' : 'running',
60
+ derivedPlanStatus: args.currentDerivedPlanStatus,
61
+ blockedFromPhase: args.reachedMaxRounds ? 'reviewer_plan' : null,
62
+ };
63
+ }
64
+ if (args.hasOpenNonBlockingFindings) {
65
+ return {
66
+ planningSignal: 'optional_revision',
67
+ phase: 'coder_plan_optional_response',
68
+ status: 'running',
69
+ derivedPlanStatus: args.currentDerivedPlanStatus,
70
+ blockedFromPhase: null,
71
+ };
72
+ }
73
+ if (args.derivedPlanReview) {
74
+ return {
75
+ planningSignal: 'accept_derived_plan',
76
+ phase: 'awaiting_derived_plan_execution',
77
+ status: 'running',
78
+ derivedPlanStatus: 'accepted',
79
+ blockedFromPhase: null,
80
+ };
81
+ }
82
+ return {
83
+ planningSignal: 'accept_plan',
84
+ phase: 'done',
85
+ status: 'done',
86
+ derivedPlanStatus: args.currentDerivedPlanStatus,
87
+ blockedFromPhase: null,
88
+ };
89
+ }
42
90
  async function buildPlanReviewerInlineContext(args) {
43
91
  const planContent = await readTextForInlineSection(resolve(args.state.cwd, args.reviewedPlanPath));
44
92
  const sections = [
@@ -2,6 +2,7 @@ import { assertNoReadPromptInstructionText, renderInlineReviewerContext, } from
2
2
  import { renderReviewerContextMarkdown } from '../context/reviewer-context.js';
3
3
  import { AUTONOMY_BLOCKED as SHARED_AUTONOMY_BLOCKED, AUTONOMY_CHUNK_DONE as SHARED_AUTONOMY_CHUNK_DONE, AUTONOMY_DONE as SHARED_AUTONOMY_DONE, AUTONOMY_SCOPE_DONE as SHARED_AUTONOMY_SCOPE_DONE, AUTONOMY_SPLIT_PLAN as SHARED_AUTONOMY_SPLIT_PLAN, buildProgressSection, getCanonicalPlanContractLines, getProtocolMarkerArtifactProhibitionLines, getStandalonePlanPayloadSourceOfTruthLines, } from '../prompts/shared.js';
4
4
  import { getUserGuidanceLines } from '../prompts/guidance.js';
5
+ import { assertPromptBuilder, resolvePrimaryVariant } from '../prompts/assert-builder.js';
5
6
  export { buildCoderResponsePrompt, buildLegacyScopePrompt, buildReviewerPrompt, buildScopePrompt } from '../prompts/execute.js';
6
7
  export { buildCoderPlanResponsePrompt, buildLegacyPlanningPrompt, buildPlanReviewerPrompt, buildPlanningPrompt, } from '../prompts/planning.js';
7
8
  export { buildFinalCompletionReviewerPrompt, buildFinalCompletionSummaryPrompt, } from '../prompts/specialized.js';
@@ -18,6 +19,8 @@ export const AUTONOMY_SPLIT_PLAN = SHARED_AUTONOMY_SPLIT_PLAN;
18
19
  // present. The static Neal-authored instructions must never reference
19
20
  // repository/file/shell access, so they pass through the shared no-read guard.
20
21
  export function buildBlockedAdjudicatorPrompt(args) {
22
+ const spec = assertPromptBuilder('blocked_adjudicator', 'buildBlockedAdjudicatorPrompt', 'src/neal/agents/prompts.ts');
23
+ resolvePrimaryVariant(spec, 'blocked_adjudicator');
21
24
  const staticInstructionLines = [
22
25
  'You are a read-only adjudicator for a blocked neal run. The run has stopped because a coder or reviewer turn reported a blocker it could not resolve on its own.',
23
26
  'Judge entirely from the inlined context sections below. You make no changes, run nothing, and look at nothing outside this prompt.',
@@ -373,6 +373,14 @@ export async function runReviewerFinalCompletionRound(args) {
373
373
  }),
374
374
  logger: args.logger,
375
375
  });
376
+ // Trust-boundary policy: rounds-level validation calls like this one are
377
+ // the authoritative trust boundary for agent payloads, not redundant dead
378
+ // code. The json-block protocol validator never runs on native
379
+ // structured-output paths, and cross-field rules are enforced only here on
380
+ // those paths; test/orchestrator.test.ts deliberately drives this wrap
381
+ // (FinalCompletionReviewerVerdictError, subtype
382
+ // final_completion_verdict_invalid) with a non-conforming fake adapter.
383
+ // Do not remove rounds-level validation calls.
376
384
  let verdict;
377
385
  try {
378
386
  verdict = parseFinalCompletionReviewerPayload(structured);