@@ -412,6 +412,7 @@ Respond with a JSON object in this minimal shape (JSON only, no markdown):
412412 "summary": "≤200 chars plain text what/why",
413413 "needsDocs": "yes" | "no" | "maybe",
414414 "docsWorthy": true | false,
415+ "newPage": true | false,
415416 "rationale": "1–2 sentence justification",
416417 "targets": [
417418 { "path": "docs/cms/...md", "anchor": "optional-section-anchor" }
@@ -469,6 +470,7 @@ Respond with a JSON object in this minimal shape (JSON only, no markdown):
469470 - Prefer targets among the "Candidate Documentation Pages" when applicable.
470471 - Include an anchor from the page's anchors list when relevant.
471472 - Keep the response JSON-only (no markdown outside JSON).
473+ - Set ` newPage: true ` only if a new documentation page should be created and no existing target fits.
472474
473475Respond ONLY with valid JSON, no markdown formatting, no additional text.` ;
474476
@@ -501,6 +503,7 @@ Respond ONLY with valid JSON, no markdown formatting, no additional text.`;
501503 const needs = ( obj . needsDocs || '' ) . toLowerCase ( ) ;
502504 const needsDocs = [ 'yes' , 'no' , 'maybe' ] . includes ( needs ) ? needs : 'maybe' ;
503505 const docsWorthy = Boolean ( obj . docsWorthy ) ;
506+ const newPage = Boolean ( obj . newPage ) ;
504507 const summary = String ( obj . summary || prAnalysis . _summary || '' ) . trim ( ) . slice ( 0 , 200 ) ;
505508 const rationale = String ( obj . rationale || '' ) . trim ( ) . slice ( 0 , 300 ) ;
506509 const targets = Array . isArray ( obj . targets ) ? obj . targets : [ ] ;
@@ -509,8 +512,16 @@ Respond ONLY with valid JSON, no markdown formatting, no additional text.`;
509512 . filter ( t => t . path ) ;
510513 const cappedTargets = normTargets . slice ( 0 , 5 ) ;
511514
512- const normalized = { summary, needsDocs, docsWorthy, rationale, targets : cappedTargets } ;
513- console . log ( ` ✅ LLM verdict: ${ needsDocs . toUpperCase ( ) } | worthy=${ docsWorthy ? 'Y' : 'N' } — ${ cappedTargets . length } target(s)` ) ;
515+ // Post-processing gate: enforce docs-worthiness and targets presence
516+ let finalNeeds = needsDocs ;
517+ if ( needsDocs === 'yes' ) {
518+ const hasTargets = cappedTargets . length > 0 ;
519+ if ( ! docsWorthy ) finalNeeds = 'no' ;
520+ else if ( ! hasTargets && ! newPage ) finalNeeds = 'no' ;
521+ }
522+
523+ const normalized = { summary, needsDocs : finalNeeds , docsWorthy, newPage, rationale, targets : cappedTargets } ;
524+ console . log ( ` ✅ LLM verdict: ${ finalNeeds . toUpperCase ( ) } | worthy=${ docsWorthy ? 'Y' : 'N' } ${ newPage ? ' | newPage=Y' : '' } — ${ cappedTargets . length } target(s)` ) ;
514525 return normalized ;
515526 } catch ( error ) {
516527 console . error ( ` ❌ Error calling Claude API: ${ error . message } ` ) ;
0 commit comments