nexus-agents 2.130.0 → 2.131.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/dist/{child-mcp-config-F7R7BFEF.js → child-mcp-config-M7WR4XBB.js} +2 -2
- package/dist/{chunk-SUJFJVAM.js → chunk-2Z4V5THE.js} +2 -2
- package/dist/{chunk-GMC6DYG7.js → chunk-3N7TSFKQ.js} +2 -2
- package/dist/{chunk-CFXL5LJC.js → chunk-3UXCVSLJ.js} +2 -2
- package/dist/{chunk-W4PM3PLE.js → chunk-3XLDANPJ.js} +7 -7
- package/dist/{chunk-KBX2Q3DG.js → chunk-4A6MSCNJ.js} +2 -2
- package/dist/{chunk-FYECPZKQ.js → chunk-5CADWTFO.js} +3 -3
- package/dist/{chunk-QENZCLR2.js → chunk-5GQMP7QN.js} +3 -3
- package/dist/{chunk-RBPGEUHT.js → chunk-7IMI64LW.js} +3 -3
- package/dist/{chunk-6BF3BRJ3.js → chunk-A4MPCXZ7.js} +2 -2
- package/dist/{chunk-BPGSM6U5.js → chunk-ACARS7NG.js} +2 -2
- package/dist/{chunk-SWKSR5R7.js → chunk-ADIJIYFA.js} +2 -2
- package/dist/{chunk-RDJMBYZ2.js → chunk-AVRE45DO.js} +3 -3
- package/dist/{chunk-JDHCHN7U.js → chunk-CMRQR57K.js} +3 -3
- package/dist/{chunk-P5TYSLNS.js → chunk-E4LAXVQE.js} +2 -2
- package/dist/{chunk-UXTCUMJM.js → chunk-EYD6O5TQ.js} +4 -4
- package/dist/chunk-EYD6O5TQ.js.map +1 -0
- package/dist/{chunk-L4ETHMN6.js → chunk-FDY6YOFG.js} +2 -2
- package/dist/{chunk-F6Y2CE24.js → chunk-FFJEERPZ.js} +2 -2
- package/dist/{chunk-CXGIRMHT.js → chunk-IZO437XR.js} +7 -7
- package/dist/{chunk-V5EI2KEG.js → chunk-KY2QMH3C.js} +5 -5
- package/dist/{chunk-TT7DZ6XW.js → chunk-OGOE3NW5.js} +4 -4
- package/dist/{chunk-4SDY75WA.js → chunk-PM4MZHQK.js} +4 -4
- package/dist/{chunk-KOICNQMN.js → chunk-RPT5WZAT.js} +64 -38
- package/dist/{chunk-KOICNQMN.js.map → chunk-RPT5WZAT.js.map} +1 -1
- package/dist/{chunk-GIKZBQY7.js → chunk-TA5HYM3H.js} +4 -4
- package/dist/{chunk-R3ZNBC2O.js → chunk-TGDWL7FG.js} +2 -2
- package/dist/{chunk-2ECAJTUP.js → chunk-ULIAUMQD.js} +2 -2
- package/dist/{chunk-LICM3H4J.js → chunk-VTTPYENR.js} +2 -2
- package/dist/{chunk-MII2DHXL.js → chunk-VY5WEC2D.js} +8 -3
- package/dist/chunk-VY5WEC2D.js.map +1 -0
- package/dist/{chunk-PP724WVD.js → chunk-YEK3ZHO6.js} +5 -5
- package/dist/{chunk-PLVZ64OM.js → chunk-YHBVFTRG.js} +2 -2
- package/dist/{chunk-AZFHCHYX.js → chunk-YXFQ3L56.js} +7 -7
- package/dist/{chunk-MJTTQCJS.js → chunk-ZM3S6PTN.js} +3 -3
- package/dist/{chunk-TULQAVRC.js → chunk-ZQ5K3PG4.js} +7 -7
- package/dist/{cli-circuit-breaker-VXHOHBE6.js → cli-circuit-breaker-XRXLO2V6.js} +4 -4
- package/dist/cli.js +39 -39
- package/dist/{composite-router-NJZMYTXG.js → composite-router-V36PBE7B.js} +2 -2
- package/dist/{consensus-vote-SH5CKJQR.js → consensus-vote-3REPKLK4.js} +13 -13
- package/dist/{context-retriever-LVW25GWO.js → context-retriever-KCSSXI6X.js} +8 -8
- package/dist/{doctor-deep-HCT3LW5G.js → doctor-deep-WID6FQ2F.js} +3 -3
- package/dist/{expert-bridge-FBYWLGB3.js → expert-bridge-F4UMZFWS.js} +4 -4
- package/dist/factory-B3SPS47O.js +21 -0
- package/dist/{factory-GP5SJCTQ.js → factory-YVHULPTE.js} +5 -5
- package/dist/{improvement-review-OUGGPW4A.js → improvement-review-AMVJW3SI.js} +4 -4
- package/dist/index.d.ts +11 -0
- package/dist/index.js +28 -28
- package/dist/{init-opencode-6PZVSSZY.js → init-opencode-3UPZL2UQ.js} +5 -5
- package/dist/{issue-triage-TPPWEE5N.js → issue-triage-U3VC5TKV.js} +5 -5
- package/dist/{pr-reviewer-helpers-MMVZFL2P.js → pr-reviewer-helpers-2WBM5GL7.js} +4 -4
- package/dist/{registry-command-IDC5G3EZ.js → registry-command-AXNA2H35.js} +2 -2
- package/dist/{repo-security-plan-XL3LTBPN.js → repo-security-plan-P2KJ4FDT.js} +3 -3
- package/dist/{research-helpers-synthesize-6ROTFLGO.js → research-helpers-synthesize-UHWT62F2.js} +4 -4
- package/dist/{routing-memory-YAW2AIRX.js → routing-memory-7RNR6A45.js} +2 -2
- package/dist/{session-memory-VR3BJMWL.js → session-memory-2J2UBZJA.js} +3 -3
- package/dist/{setup-command-SMJX3TES.js → setup-command-UF7EQKAL.js} +11 -11
- package/dist/{setup-config-IXZAAYYH.js → setup-config-Y3S2L4RD.js} +3 -3
- package/dist/{setup-custom-api-6ZBOVWEU.js → setup-custom-api-AZMHKIHE.js} +3 -3
- package/dist/{tool-memory-ZKMPHKG5.js → tool-memory-MIZVB4ZT.js} +5 -5
- package/dist/{unified-registry-WP4XC656.js → unified-registry-V4AZ6UYA.js} +9 -9
- package/dist/{weather-report-CETWTNE5.js → weather-report-WZKEEAC7.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-MII2DHXL.js.map +0 -1
- package/dist/chunk-UXTCUMJM.js.map +0 -1
- package/dist/factory-5IYTNTA2.js +0 -21
- /package/dist/{child-mcp-config-F7R7BFEF.js.map → child-mcp-config-M7WR4XBB.js.map} +0 -0
- /package/dist/{chunk-SUJFJVAM.js.map → chunk-2Z4V5THE.js.map} +0 -0
- /package/dist/{chunk-GMC6DYG7.js.map → chunk-3N7TSFKQ.js.map} +0 -0
- /package/dist/{chunk-CFXL5LJC.js.map → chunk-3UXCVSLJ.js.map} +0 -0
- /package/dist/{chunk-W4PM3PLE.js.map → chunk-3XLDANPJ.js.map} +0 -0
- /package/dist/{chunk-KBX2Q3DG.js.map → chunk-4A6MSCNJ.js.map} +0 -0
- /package/dist/{chunk-FYECPZKQ.js.map → chunk-5CADWTFO.js.map} +0 -0
- /package/dist/{chunk-QENZCLR2.js.map → chunk-5GQMP7QN.js.map} +0 -0
- /package/dist/{chunk-RBPGEUHT.js.map → chunk-7IMI64LW.js.map} +0 -0
- /package/dist/{chunk-6BF3BRJ3.js.map → chunk-A4MPCXZ7.js.map} +0 -0
- /package/dist/{chunk-BPGSM6U5.js.map → chunk-ACARS7NG.js.map} +0 -0
- /package/dist/{chunk-SWKSR5R7.js.map → chunk-ADIJIYFA.js.map} +0 -0
- /package/dist/{chunk-RDJMBYZ2.js.map → chunk-AVRE45DO.js.map} +0 -0
- /package/dist/{chunk-JDHCHN7U.js.map → chunk-CMRQR57K.js.map} +0 -0
- /package/dist/{chunk-P5TYSLNS.js.map → chunk-E4LAXVQE.js.map} +0 -0
- /package/dist/{chunk-L4ETHMN6.js.map → chunk-FDY6YOFG.js.map} +0 -0
- /package/dist/{chunk-F6Y2CE24.js.map → chunk-FFJEERPZ.js.map} +0 -0
- /package/dist/{chunk-CXGIRMHT.js.map → chunk-IZO437XR.js.map} +0 -0
- /package/dist/{chunk-V5EI2KEG.js.map → chunk-KY2QMH3C.js.map} +0 -0
- /package/dist/{chunk-TT7DZ6XW.js.map → chunk-OGOE3NW5.js.map} +0 -0
- /package/dist/{chunk-4SDY75WA.js.map → chunk-PM4MZHQK.js.map} +0 -0
- /package/dist/{chunk-GIKZBQY7.js.map → chunk-TA5HYM3H.js.map} +0 -0
- /package/dist/{chunk-R3ZNBC2O.js.map → chunk-TGDWL7FG.js.map} +0 -0
- /package/dist/{chunk-2ECAJTUP.js.map → chunk-ULIAUMQD.js.map} +0 -0
- /package/dist/{chunk-LICM3H4J.js.map → chunk-VTTPYENR.js.map} +0 -0
- /package/dist/{chunk-PP724WVD.js.map → chunk-YEK3ZHO6.js.map} +0 -0
- /package/dist/{chunk-PLVZ64OM.js.map → chunk-YHBVFTRG.js.map} +0 -0
- /package/dist/{chunk-AZFHCHYX.js.map → chunk-YXFQ3L56.js.map} +0 -0
- /package/dist/{chunk-MJTTQCJS.js.map → chunk-ZM3S6PTN.js.map} +0 -0
- /package/dist/{chunk-TULQAVRC.js.map → chunk-ZQ5K3PG4.js.map} +0 -0
- /package/dist/{cli-circuit-breaker-VXHOHBE6.js.map → cli-circuit-breaker-XRXLO2V6.js.map} +0 -0
- /package/dist/{composite-router-NJZMYTXG.js.map → composite-router-V36PBE7B.js.map} +0 -0
- /package/dist/{consensus-vote-SH5CKJQR.js.map → consensus-vote-3REPKLK4.js.map} +0 -0
- /package/dist/{context-retriever-LVW25GWO.js.map → context-retriever-KCSSXI6X.js.map} +0 -0
- /package/dist/{doctor-deep-HCT3LW5G.js.map → doctor-deep-WID6FQ2F.js.map} +0 -0
- /package/dist/{expert-bridge-FBYWLGB3.js.map → expert-bridge-F4UMZFWS.js.map} +0 -0
- /package/dist/{factory-5IYTNTA2.js.map → factory-B3SPS47O.js.map} +0 -0
- /package/dist/{factory-GP5SJCTQ.js.map → factory-YVHULPTE.js.map} +0 -0
- /package/dist/{improvement-review-OUGGPW4A.js.map → improvement-review-AMVJW3SI.js.map} +0 -0
- /package/dist/{init-opencode-6PZVSSZY.js.map → init-opencode-3UPZL2UQ.js.map} +0 -0
- /package/dist/{issue-triage-TPPWEE5N.js.map → issue-triage-U3VC5TKV.js.map} +0 -0
- /package/dist/{pr-reviewer-helpers-MMVZFL2P.js.map → pr-reviewer-helpers-2WBM5GL7.js.map} +0 -0
- /package/dist/{registry-command-IDC5G3EZ.js.map → registry-command-AXNA2H35.js.map} +0 -0
- /package/dist/{repo-security-plan-XL3LTBPN.js.map → repo-security-plan-P2KJ4FDT.js.map} +0 -0
- /package/dist/{research-helpers-synthesize-6ROTFLGO.js.map → research-helpers-synthesize-UHWT62F2.js.map} +0 -0
- /package/dist/{routing-memory-YAW2AIRX.js.map → routing-memory-7RNR6A45.js.map} +0 -0
- /package/dist/{session-memory-VR3BJMWL.js.map → session-memory-2J2UBZJA.js.map} +0 -0
- /package/dist/{setup-command-SMJX3TES.js.map → setup-command-UF7EQKAL.js.map} +0 -0
- /package/dist/{setup-config-IXZAAYYH.js.map → setup-config-Y3S2L4RD.js.map} +0 -0
- /package/dist/{setup-custom-api-6ZBOVWEU.js.map → setup-custom-api-AZMHKIHE.js.map} +0 -0
- /package/dist/{tool-memory-ZKMPHKG5.js.map → tool-memory-MIZVB4ZT.js.map} +0 -0
- /package/dist/{unified-registry-WP4XC656.js.map → unified-registry-V4AZ6UYA.js.map} +0 -0
- /package/dist/{weather-report-CETWTNE5.js.map → weather-report-WZKEEAC7.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/security/trust-classifier.ts","../src/security/policy-gate.ts","../src/security/action-schema.ts","../src/security/audit-trail.ts","../src/security/corroboration-validator.ts","../src/scm/url-parsers.ts","../src/scm/github-provider-traits.ts","../src/dogfooding/issue-triage-types.ts","../src/dogfooding/issue-triage-helpers.ts","../src/dogfooding/issue-triage.ts"],"sourcesContent":["/**\n * nexus-agents/security - Trust Classifier\n *\n * Classifies GitHub users and content into trust tiers based on\n * repository relationship, allowlist membership, and content analysis.\n * Works with the input sanitizer to determine how agent decisions\n * should weight each input source.\n *\n * @module security/trust-classifier\n * (Source: Issue #818, #819 — Phase 1: Input Sanitization)\n */\n\nimport type { TrustTier, GitHubUserRole, SanitizedInput, SanitizerConfig } from './trust-types.js';\nimport { ROLE_DEFAULT_TRUST, TRUST_TIER_NUMERIC } from './trust-types.js';\n\n// ============================================================================\n// GitHub Author Association Mapping\n// ============================================================================\n\n/**\n * Maps GitHub API author_association values to our GitHubUserRole enum.\n * See: https://docs.github.com/en/graphql/reference/enums#commentauthorassociation\n */\nexport function mapAuthorAssociation(association: string): GitHubUserRole {\n switch (association.toUpperCase()) {\n case 'OWNER':\n return 'owner';\n case 'MEMBER':\n return 'member';\n case 'COLLABORATOR':\n return 'collaborator';\n case 'CONTRIBUTOR':\n return 'contributor';\n case 'FIRST_TIMER':\n case 'FIRST_TIME_CONTRIBUTOR':\n case 'NONE':\n return 'unknown';\n case 'MANNEQUIN':\n return 'unknown';\n default:\n return 'unknown';\n }\n}\n\n// ============================================================================\n// Trust Classification\n// ============================================================================\n\n/**\n * Input for trust classification.\n */\nexport interface ClassifyInput {\n /** GitHub username. */\n readonly username: string;\n /** GitHub API author_association value. */\n readonly authorAssociation: string;\n /** Sanitized input (if content has already been through the sanitizer). */\n readonly sanitizedInput?: SanitizedInput;\n /** Sanitizer config (for allowlist check). */\n readonly config?: Partial<SanitizerConfig>;\n}\n\n/**\n * Result of trust classification.\n */\nexport interface ClassifyResult {\n /** Assigned trust tier. */\n readonly trustTier: TrustTier;\n /** GitHub user role. */\n readonly userRole: GitHubUserRole;\n /** Whether the user is on the maintainer allowlist. */\n readonly isAllowlisted: boolean;\n /** Whether content triggered a trust downgrade. */\n readonly wasDowngraded: boolean;\n /** Reason for the assigned tier. */\n readonly reason: string;\n}\n\n/**\n * Classifies a GitHub user and their content into a trust tier.\n *\n * The trust tier is determined by:\n * 1. Allowlist membership (always Tier 1)\n * 2. GitHub author_association → role → default tier\n * 3. Content injection analysis (can only downgrade, never upgrade)\n *\n * ⚠ **Use HostileInputFirewall.process() in agent code paths.** Calling\n * classifyTrust() directly skips the Rule-of-Two check in policy-gate\n * and does not emit audit-trail events. The firewall is the canonical\n * entry point for agent decisions; direct use is for unit tests and\n * non-decision analysis only.\n *\n * @see packages/nexus-agents/src/security/firewall/firewall-pipeline.ts\n * @see packages/nexus-agents/src/security/policy-gate.ts\n */\nexport function classifyTrust(input: ClassifyInput): ClassifyResult {\n const allowlistedMaintainers = input.config?.allowlistedMaintainers ?? [];\n const isAllowlisted = allowlistedMaintainers.includes(input.username);\n const userRole = mapAuthorAssociation(input.authorAssociation);\n\n if (isAllowlisted) {\n return {\n trustTier: '1',\n userRole,\n isAllowlisted: true,\n wasDowngraded: false,\n reason: `User ${input.username} is on the maintainer allowlist`,\n };\n }\n\n const baseTier = ROLE_DEFAULT_TRUST[userRole];\n\n // If sanitized input available, check for downgrade\n if (input.sanitizedInput !== undefined) {\n const contentTier = input.sanitizedInput.trustTier;\n const downgraded = TRUST_TIER_NUMERIC[contentTier] > TRUST_TIER_NUMERIC[baseTier];\n\n return {\n trustTier: downgraded ? contentTier : baseTier,\n userRole,\n isAllowlisted: false,\n wasDowngraded: downgraded,\n reason: downgraded\n ? `Downgraded from Tier ${baseTier} to ${contentTier}: injection patterns detected`\n : `Role ${userRole} → Tier ${baseTier}`,\n };\n }\n\n return {\n trustTier: baseTier,\n userRole,\n isAllowlisted: false,\n wasDowngraded: false,\n reason: `Role ${userRole} → Tier ${baseTier}`,\n };\n}\n\n/**\n * Checks whether a trust tier can influence agent decisions.\n * Tiers 3-4 are informational only — they cannot drive actions.\n */\nexport function canInfluenceDecisions(tier: TrustTier): boolean {\n return TRUST_TIER_NUMERIC[tier] <= 2;\n}\n\n/**\n * Checks whether a trust tier requires corroboration with Tier 1 sources.\n * Tier 2 requires corroboration; Tier 1 is self-sufficient.\n */\nexport function requiresCorroboration(tier: TrustTier): boolean {\n return tier === '2';\n}\n\n/**\n * Returns the minimum trust tier required for a given action type.\n * Actions that modify state require higher trust.\n */\nexport function getRequiredTrustTier(actionType: string): TrustTier {\n switch (actionType) {\n case 'GeneratePatchPlan':\n return '1'; // Requires maintainer-level trust\n case 'DraftReply':\n case 'ProposeLabels':\n return '2'; // Requires at least collaborator-level trust\n case 'SummarizeIssue':\n case 'ClassifyIssue':\n case 'IdentifyDuplicates':\n return '3'; // Read-only, can use any input\n case 'RequestHumanApproval':\n case 'RefuseAction':\n return '4'; // Always allowed (safety actions)\n default:\n return '1'; // Unknown actions require highest trust\n }\n}\n","/**\n * nexus-agents/security - Policy Gate\n *\n * Deterministic rule engine that validates all agent actions before\n * GitHub state mutations can occur. No LLM in the validation path.\n *\n * Defense layer 2 of the three-layer hardening architecture.\n * See: docs/architecture/UNTRUSTED_INPUT_HARDENING.md\n *\n * @module security/policy-gate\n * (Source: Issue #818, #822 — Phase 2: Policy Gate)\n */\n\nimport { z } from 'zod';\n\nimport type { AgentAction, AgentActionType, SourceCitation } from './action-schema.js';\nimport { isMutatingAction, isReadOnlyAction, requiresCitation } from './action-schema.js';\nimport type { TrustTier } from './trust-types.js';\nimport { TRUST_TIER_NUMERIC } from './trust-types.js';\nimport { getRequiredTrustTier, canInfluenceDecisions } from './trust-classifier.js';\nimport type { AuditTrail } from './audit-trail.js';\nimport { emitPolicyEvent } from './audit-trail.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Violation detected by the policy gate.\n */\nexport const ViolationSchema = z.object({\n /** Machine-readable rule identifier. */\n rule: z.string().min(1),\n /** Human-readable description of the violation. */\n message: z.string().min(1),\n /** Severity: 'block' prevents execution, 'warn' logs only. */\n severity: z.enum(['block', 'warn']),\n});\nexport type Violation = z.infer<typeof ViolationSchema>;\n\n/**\n * Decision returned by the policy gate.\n */\nexport interface PolicyDecision {\n /** Whether the action is allowed to proceed. */\n readonly allowed: boolean;\n /** Whether human approval is required before execution. */\n readonly requiresApproval: boolean;\n /** All detected violations (blocking and warnings). */\n readonly violations: readonly Violation[];\n /** Timestamp of the evaluation (ISO 8601). */\n readonly evaluatedAt: string;\n}\n\n/**\n * Context for evaluating a policy decision.\n */\nexport interface ActionContext {\n /** Trust tier of the primary input source. */\n readonly inputTrustTier: TrustTier;\n /** Whether the agent currently has write access to the repository. */\n readonly hasWriteAccess: boolean;\n /** Whether the agent currently has access to secrets/tokens. */\n readonly hasSecretAccess: boolean;\n /** Set of labels that exist on the repository (for ProposeLabels validation). */\n readonly existingLabels?: ReadonlySet<string>;\n}\n\n// ============================================================================\n// Policy Rules\n// ============================================================================\n\n/** Extract sources from an action, handling actions that lack a sources field. */\nfunction getActionSources(action: AgentAction): readonly SourceCitation[] {\n if ('sources' in action) {\n return action.sources;\n }\n return [];\n}\n\n/** Check that citations exist for actions that require them. */\nfunction checkCitationRequirement(action: AgentAction): Violation | undefined {\n if (!requiresCitation(action.type)) return undefined;\n const sources = getActionSources(action);\n if (sources.length === 0) {\n return {\n rule: 'REQUIRE_CITATION',\n message: `Action '${action.type}' requires at least one source citation`,\n severity: 'block',\n };\n }\n return undefined;\n}\n\n/** Check that the input trust tier meets action requirements. */\nfunction checkTrustRequirement(action: AgentAction, context: ActionContext): Violation | undefined {\n const requiredTier = getRequiredTrustTier(action.type);\n const requiredNumeric = TRUST_TIER_NUMERIC[requiredTier];\n const inputNumeric = TRUST_TIER_NUMERIC[context.inputTrustTier];\n\n if (inputNumeric > requiredNumeric) {\n return {\n rule: 'INSUFFICIENT_TRUST',\n message: `Action '${action.type}' requires Tier ${requiredTier} but input is Tier ${context.inputTrustTier}`,\n severity: 'block',\n };\n }\n return undefined;\n}\n\n/** Check that Tier 3-4 input cannot drive decisions. */\nfunction checkInfluenceBlock(action: AgentAction, context: ActionContext): Violation | undefined {\n if (!canInfluenceDecisions(context.inputTrustTier) && isMutatingAction(action.type)) {\n return {\n rule: 'UNTRUSTED_INFLUENCE',\n message: `Tier ${context.inputTrustTier} input cannot drive mutating action '${action.type}'`,\n severity: 'block',\n };\n }\n return undefined;\n}\n\n/**\n * Enforce the Rule of Two: no agent may simultaneously\n * (a) process untrusted input, (b) have write access, AND (c) access secrets.\n *\n * Exported (#3198) so the firewall's `policyEnforcement` stage can surface the\n * same assessment during input composition without duplicating the predicate.\n */\nexport function checkRuleOfTwo(context: ActionContext): Violation | undefined {\n const isUntrusted = TRUST_TIER_NUMERIC[context.inputTrustTier] >= 3;\n if (isUntrusted && context.hasWriteAccess && context.hasSecretAccess) {\n return {\n rule: 'RULE_OF_TWO',\n message:\n 'Rule of Two violation: agent simultaneously processes untrusted input, has write access, and accesses secrets',\n severity: 'block',\n };\n }\n return undefined;\n}\n\n/** Check that proposed labels exist in the repository's label set. */\nfunction checkLabelValidity(action: AgentAction, context: ActionContext): Violation | undefined {\n if (action.type !== 'ProposeLabels') return undefined;\n const labels = context.existingLabels;\n if (labels === undefined) return undefined;\n\n const invalid = action.labels.filter((l) => !labels.has(l));\n if (invalid.length > 0) {\n return {\n rule: 'INVALID_LABELS',\n message: `Proposed labels not in repository: ${invalid.join(', ')}`,\n severity: 'block',\n };\n }\n return undefined;\n}\n\n/** Check that source citations meet trust requirements for the action. */\nfunction checkSourceTrustTiers(action: AgentAction): Violation | undefined {\n const sources = getActionSources(action);\n if (sources.length === 0) return undefined;\n\n const requiredTier = getRequiredTrustTier(action.type);\n const requiredNumeric = TRUST_TIER_NUMERIC[requiredTier];\n\n for (const source of sources) {\n if (source.type === 'issueComment') {\n const sourceTierNumeric = TRUST_TIER_NUMERIC[source.authorTrustTier];\n if (sourceTierNumeric > requiredNumeric) {\n return {\n rule: 'SOURCE_TRUST_MISMATCH',\n message: `Source from '${source.author}' (Tier ${source.authorTrustTier}) insufficient for action requiring Tier ${requiredTier}`,\n severity: 'warn',\n };\n }\n }\n }\n return undefined;\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Evaluate an agent action against the policy gate.\n *\n * This is a deterministic check — no LLM in the loop. Returns a\n * PolicyDecision indicating whether the action is allowed, requires\n * human approval, or is blocked.\n *\n * @param action - The validated AgentAction to evaluate.\n * @param context - The current execution context.\n * @returns PolicyDecision with violations and approval requirements.\n */\nexport function evaluatePolicy(\n action: AgentAction,\n context: ActionContext,\n auditTrail?: AuditTrail\n): PolicyDecision {\n const violations: Violation[] = [];\n\n const checks = [\n checkCitationRequirement(action),\n checkTrustRequirement(action, context),\n checkInfluenceBlock(action, context),\n checkRuleOfTwo(context),\n checkLabelValidity(action, context),\n checkSourceTrustTiers(action),\n ];\n\n for (const violation of checks) {\n if (violation !== undefined) {\n violations.push(violation);\n }\n }\n\n const hasBlockingViolation = violations.some((v) => v.severity === 'block');\n const needsApproval = !hasBlockingViolation && isMutatingAction(action.type);\n\n const decision: PolicyDecision = {\n allowed: !hasBlockingViolation,\n requiresApproval: needsApproval,\n violations,\n evaluatedAt: new Date().toISOString(),\n };\n\n // #3191: when an audit trail is supplied, record the decision so policy\n // outcomes are part of the durable audit record (the gate previously emitted\n // nothing). Optional — pure callers pass no trail and incur no side effect.\n if (auditTrail !== undefined) {\n emitPolicyEvent(auditTrail, {\n actionType: action.type,\n allowed: decision.allowed,\n requiresApproval: decision.requiresApproval,\n inputTrustTier: context.inputTrustTier,\n violationRules: violations.map((v) => v.rule),\n });\n }\n\n return decision;\n}\n\n/**\n * Quick check: can this action type proceed at all given the input trust tier?\n * Useful for early rejection before full policy evaluation.\n */\nexport function canProceed(actionType: AgentActionType, inputTrustTier: TrustTier): boolean {\n if (isReadOnlyAction(actionType)) {\n const requiredTier = getRequiredTrustTier(actionType);\n return TRUST_TIER_NUMERIC[inputTrustTier] <= TRUST_TIER_NUMERIC[requiredTier];\n }\n return canInfluenceDecisions(inputTrustTier);\n}\n","/**\n * nexus-agents/security - Typed Action Schema\n *\n * Zod schemas and TypeScript types for the typed action constraint system.\n * Agents processing untrusted GitHub input MUST emit only predefined typed\n * actions (never free-form tool calls). This module defines those action\n * schemas, validates them at runtime, and classifies them as read-only or\n * mutating for the policy gate.\n *\n * @module security/action-schema\n * (Source: Issue #818, #820)\n */\n\nimport { z } from 'zod';\n\nimport { TrustTierSchema } from './trust-types.js';\n\n// ============================================================================\n// Result Type (local — avoids circular dependency with core/types)\n// ============================================================================\n\n/** Validation result using the project Result pattern. */\nexport type ActionValidationResult =\n | { ok: true; value: AgentAction }\n | { ok: false; error: string };\n\n// ============================================================================\n// Source Citations\n// ============================================================================\n\n/** Source citation from a file tracked in the repository. */\nconst RepoFileSource = z.object({\n type: z.literal('repoFile'),\n path: z.string().min(1),\n line: z.number().int().positive().optional(),\n commit: z\n .string()\n .regex(/^[a-f0-9]{7,40}$/)\n .optional(),\n});\n\n/** Source citation from a GitHub issue comment. */\nconst IssueCommentSource = z.object({\n type: z.literal('issueComment'),\n issueNumber: z.number().int().positive(),\n commentId: z.number().int().positive(),\n author: z.string().min(1),\n authorTrustTier: TrustTierSchema,\n});\n\n/** Source citation from a CI pipeline result. */\nconst CIResultSource = z.object({\n type: z.literal('ciResult'),\n runId: z.number().int().positive(),\n status: z.enum(['pass', 'fail']),\n job: z.string().min(1),\n});\n\n/** Source citation from a policy or governance document. */\nconst PolicyDocSource = z.object({\n type: z.literal('policyDoc'),\n path: z.string().min(1),\n section: z.string().min(1),\n});\n\n/** Source citation from a maintainer slash-command or explicit instruction. */\nconst MaintainerCommandSource = z.object({\n type: z.literal('maintainerCommand'),\n username: z.string().min(1),\n commentId: z.number().int().positive(),\n});\n\n/**\n * Discriminated union of all valid source citation types.\n * Every decision-making action MUST cite at least one source.\n */\nexport const SourceCitationSchema = z.discriminatedUnion('type', [\n RepoFileSource,\n IssueCommentSource,\n CIResultSource,\n PolicyDocSource,\n MaintainerCommandSource,\n]);\n\n/** Inferred TypeScript type for a source citation. */\nexport type SourceCitation = z.infer<typeof SourceCitationSchema>;\n\n// ============================================================================\n// Typed Actions\n// ============================================================================\n\n/** Read-only analysis action: summarize an issue with citations. */\nconst SummarizeIssueAction = z.object({\n type: z.literal('SummarizeIssue'),\n summary: z.string().min(10).max(2000),\n sources: z.array(SourceCitationSchema).min(1).max(20),\n});\n\n/** Suggest labels for an issue (max 5, must match existing label set). */\nconst ProposeLabelsAction = z.object({\n type: z.literal('ProposeLabels'),\n labels: z.array(z.string()).min(1).max(5),\n reason: z.string().min(10).max(500),\n sources: z.array(SourceCitationSchema).min(1).max(20),\n});\n\n/** Draft a reply comment (always requires human approval before posting). */\nconst DraftReplyAction = z.object({\n type: z.literal('DraftReply'),\n body: z.string().min(10).max(2000),\n requiresApproval: z.literal(true),\n sources: z.array(SourceCitationSchema).min(1).max(20),\n});\n\n/** Explicit escalation to a human maintainer with reason and context. */\nconst RequestHumanApprovalAction = z.object({\n type: z.literal('RequestHumanApproval'),\n reason: z.string().min(10).max(500),\n context: z.string().min(10).max(2000),\n});\n\n/**\n * Propose a set of file modifications (requires maintainer corroboration).\n * Forbidden from Tier 3-4 input without maintainer corroboration.\n */\nconst GeneratePatchPlanAction = z.object({\n type: z.literal('GeneratePatchPlan'),\n files: z\n .array(\n z.object({\n path: z.string().min(1),\n operation: z.enum(['modify', 'create', 'delete']),\n description: z.string().min(10).max(500),\n })\n )\n .min(1)\n .max(10),\n rationale: z.string().min(10).max(1000),\n requiresApproval: z.literal(true),\n sources: z.array(SourceCitationSchema).min(2).max(20),\n});\n\n/** Categorize an issue by type with confidence score. */\nconst ClassifyIssueAction = z.object({\n type: z.literal('ClassifyIssue'),\n category: z.enum(['bug', 'feature', 'question', 'documentation', 'security', 'performance']),\n confidence: z.number().min(0).max(1),\n sources: z.array(SourceCitationSchema).min(1).max(20),\n});\n\n/** Identify potential duplicate issues with similarity scores. */\nconst IdentifyDuplicatesAction = z.object({\n type: z.literal('IdentifyDuplicates'),\n candidates: z.array(z.number().int().positive()).min(1).max(10),\n similarity: z.array(z.number().min(0).max(1)),\n sources: z.array(SourceCitationSchema).min(1).max(20),\n});\n\n/** Explicit refusal to act, with escalation target. */\nconst RefuseActionAction = z.object({\n type: z.literal('RefuseAction'),\n reason: z.string().min(10).max(500),\n escalateTo: z.enum(['maintainer', 'security']),\n});\n\n/** Handoff delegation from one agent to another by capability. (Issue #834) */\nconst HandoffMessageAction = z.object({\n type: z.literal('HandoffMessage'),\n targetCapability: z.string().min(1).max(100),\n reason: z.string().min(5).max(500),\n inputTrustTier: z.enum(['1', '2', '3', '4']),\n sources: z.array(SourceCitationSchema).min(1).max(20),\n});\n\n/**\n * Discriminated union of all valid agent actions.\n * This is the ONLY schema agents may emit when processing untrusted input.\n */\nexport const AgentActionSchema = z.discriminatedUnion('type', [\n SummarizeIssueAction,\n ProposeLabelsAction,\n DraftReplyAction,\n RequestHumanApprovalAction,\n GeneratePatchPlanAction,\n ClassifyIssueAction,\n IdentifyDuplicatesAction,\n RefuseActionAction,\n HandoffMessageAction,\n]);\n\n/** Inferred TypeScript type for an agent action. */\nexport type AgentAction = z.infer<typeof AgentActionSchema>;\n\n/** All valid action type discriminator values. */\nexport type AgentActionType = AgentAction['type'];\n\n// ============================================================================\n// Action Classification\n// ============================================================================\n\n/**\n * Action types that are read-only and do not modify GitHub state.\n * These can be executed without human approval (subject to policy gate).\n */\nconst READ_ONLY_ACTIONS: ReadonlySet<AgentActionType> = new Set<AgentActionType>([\n 'SummarizeIssue',\n 'ClassifyIssue',\n 'IdentifyDuplicates',\n 'RefuseAction',\n 'RequestHumanApproval',\n 'HandoffMessage',\n]);\n\n/**\n * Action types that can modify GitHub state (labels, comments, code).\n * These always require human approval before execution.\n */\nconst MUTATING_ACTIONS: ReadonlySet<AgentActionType> = new Set<AgentActionType>([\n 'ProposeLabels',\n 'DraftReply',\n 'GeneratePatchPlan',\n]);\n\n/**\n * Action types that MUST include at least one source citation.\n * Escalation and refusal actions are exempt (they report inability to act).\n */\nconst CITATION_REQUIRED_ACTIONS: ReadonlySet<AgentActionType> = new Set<AgentActionType>([\n 'SummarizeIssue',\n 'ProposeLabels',\n 'DraftReply',\n 'GeneratePatchPlan',\n 'ClassifyIssue',\n 'IdentifyDuplicates',\n 'HandoffMessage',\n]);\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Validate an unknown value against the AgentActionSchema.\n * Returns a Result: `{ ok: true; value }` on success or `{ ok: false; error }` on failure.\n *\n * @param input - The value to validate (typically parsed JSON from an agent).\n * @returns Validation result following the project Result pattern.\n */\nexport function validateAgentAction(input: unknown): ActionValidationResult {\n const result = AgentActionSchema.safeParse(input);\n if (result.success) {\n return { ok: true, value: result.data };\n }\n const messages = result.error.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`);\n return { ok: false, error: `Action validation failed: ${messages.join('; ')}` };\n}\n\n/**\n * Check whether an action type is read-only (does not modify GitHub state).\n *\n * @param actionType - The action type discriminator value.\n * @returns True if the action is read-only.\n */\nexport function isReadOnlyAction(actionType: AgentActionType): boolean {\n return READ_ONLY_ACTIONS.has(actionType);\n}\n\n/**\n * Check whether an action type can modify GitHub state.\n * Mutating actions always require human approval before execution.\n *\n * @param actionType - The action type discriminator value.\n * @returns True if the action can modify state.\n */\nexport function isMutatingAction(actionType: AgentActionType): boolean {\n return MUTATING_ACTIONS.has(actionType);\n}\n\n/**\n * Check whether an action type requires at least one source citation.\n * Escalation (RequestHumanApproval) and refusal (RefuseAction) are exempt.\n *\n * @param actionType - The action type discriminator value.\n * @returns True if the action must include source citations.\n */\nexport function requiresCitation(actionType: AgentActionType): boolean {\n return CITATION_REQUIRED_ACTIONS.has(actionType);\n}\n","/**\n * nexus-agents/security - Audit Trail\n *\n * Machine-readable JSON audit events for security pipeline decisions.\n * Every trust classification, policy gate decision, corroboration check,\n * and reputation assessment is recorded as a structured event.\n *\n * Satisfies CLAUDE.md requirement: \"Every action on untrusted input must\n * log: trust tier, sources cited, policy gate decision, stripped content.\"\n *\n * @module security/audit-trail\n * (Source: Issue #832 — Security audit trail)\n */\n\nimport { getTimeProvider } from '../core/index.js';\nimport type { TrustTier } from './trust-types.js';\nimport type { AgentActionType } from './action-schema.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Maximum stored events before oldest are evicted. */\nconst MAX_EVENTS = 10_000;\n\n/**\n * Discriminated union of audit event types.\n * Each event captures a single security pipeline decision.\n */\nexport type AuditEvent =\n | TrustClassificationEvent\n | PolicyGateEvent\n | CorroborationEvent\n | ReputationEvent\n | SanitizationEvent\n | GraphExecutionAuditEvent;\n\n/** Base fields shared by all audit events. */\ninterface AuditEventBase {\n readonly id: string;\n readonly timestamp: string;\n readonly component: string;\n}\n\n/** Trust classification decision. */\nexport interface TrustClassificationEvent extends AuditEventBase {\n readonly type: 'trust_classification';\n readonly username: string;\n readonly assignedTier: TrustTier;\n readonly userRole: string;\n readonly isAllowlisted: boolean;\n readonly wasDowngraded: boolean;\n readonly reason: string;\n}\n\n/** Policy gate evaluation result. */\nexport interface PolicyGateEvent extends AuditEventBase {\n readonly type: 'policy_gate';\n /**\n * The agent action evaluated, for the security policy-gate path\n * (security/policy-gate.ts). Optional because the PIPELINE policy path\n * (pipeline/policy-evaluator.ts → #3710) records stage-boundary policy\n * decisions that have no `AgentAction` — they carry {@link stageType} +\n * {@link mode} + {@link ruleIds} instead. Security emitters always set it.\n */\n readonly actionType?: AgentActionType;\n readonly allowed: boolean;\n readonly requiresApproval: boolean;\n readonly inputTrustTier: TrustTier;\n readonly violationRules: readonly string[];\n /**\n * Pipeline-policy fields (#3710). Carried for the dev-pipeline\n * consensus→execute seam so the DURABLE record can distinguish soak (`warn`)\n * from enforce (`block`) and which rules/stage fired — without these the\n * persisted event is useless to the tune/readiness loop. Absent for the\n * security policy-gate path.\n */\n /** Enforcement mode the decision was made under: `warn` (soak) or `block` (enforce). */\n readonly mode?: 'off' | 'warn' | 'block';\n /** IDs of the policy rules that fired (mirrors `violationRules` for the pipeline path). */\n readonly ruleIds?: readonly string[];\n /** Type of the stage the gate guarded (e.g. `execute`). */\n readonly stageType?: string;\n /**\n * #3727: discriminates a per-EVALUATION SUMMARY record (`'summary'` — emitted\n * once per pipeline policy evaluation INCLUDING clean ones, the DENOMINATOR for\n * the would-block rate) from a per-VIOLATION record (`'violation'` — the\n * existing #3710 per-violation records). Absent for the security policy-gate\n * path. Denominator = count(recordKind==='summary'); numerator = summaries with\n * `violationCount > 0`. Scope the #3710 count-parity assertion to `'violation'`.\n */\n readonly recordKind?: 'summary' | 'violation';\n /** #3727: number of violations in THIS evaluation (set on the summary record). */\n readonly violationCount?: number;\n}\n\n/** Corroboration validation result. */\nexport interface CorroborationEvent extends AuditEventBase {\n readonly type: 'corroboration';\n readonly actionType: AgentActionType;\n readonly satisfied: boolean;\n readonly sourceCount: number;\n readonly missingRequirements: readonly string[];\n}\n\n/** Reputation assessment result. */\nexport interface ReputationEvent extends AuditEventBase {\n readonly type: 'reputation';\n readonly username: string;\n readonly reputationScore: number;\n readonly isSuspicious: boolean;\n readonly effectiveTier: TrustTier;\n readonly signalCount: number;\n}\n\n/** Summary of a single element stripped during sanitization. */\nexport interface StrippedElementSummary {\n /** Truncated tag text (≤30 chars + '...' from the sanitizer). */\n readonly tag: string;\n /** Reason the element was removed (e.g. 'Trail of Bits injection vector'). */\n readonly reason: string;\n}\n\n/** Max stripped-element details retained per sanitization event. */\nexport const MAX_STRIPPED_ELEMENTS_PER_EVENT = 20;\n\n/** Input sanitization result. */\nexport interface SanitizationEvent extends AuditEventBase {\n readonly type: 'sanitization';\n readonly source: string;\n readonly wasModified: boolean;\n readonly strippedCount: number;\n readonly injectionFlagCount: number;\n /**\n * Per-element tag/reason details, truncated to at most\n * MAX_STRIPPED_ELEMENTS_PER_EVENT entries. Required by CLAUDE.md's\n * Untrusted Input Policy: \"Log stripped elements for audit trail.\"\n */\n readonly strippedElements: readonly StrippedElementSummary[];\n}\n\n/** Graph execution lifecycle event (Issue #839). */\nexport interface GraphExecutionAuditEvent extends AuditEventBase {\n readonly type: 'graph_execution';\n readonly graphEvent: string;\n readonly nodeId?: string;\n readonly stepNumber: number;\n readonly detail: string;\n}\n\n/**\n * Query filter for retrieving audit events.\n *\n * The post-mortem dimensions (#3197) — `actionType`, `actor`, `violationRule`\n * — NARROW to events that actually carry the field (events lacking it are\n * excluded), unlike `trustTier`'s legacy keep-non-applicable behavior. Only\n * dimensions backed by a real event field are offered: `resource` and\n * `policyName` from the original ask were dropped because no AuditEvent\n * records them (a filter with no backing field would be dead config); the\n * policy-rule intent is served by `violationRule` (PolicyGateEvent's\n * `violationRules`).\n */\nexport interface AuditQuery {\n readonly type?: AuditEvent['type'];\n readonly since?: string;\n readonly until?: string;\n readonly trustTier?: TrustTier;\n /** Match PolicyGate/Corroboration events by their `actionType`. */\n readonly actionType?: AgentActionType;\n /** Match Trust/Reputation events by `username` (the acting/assessed user). */\n readonly actor?: string;\n /** Match PolicyGate events whose `violationRules` include this rule name. */\n readonly violationRule?: string;\n readonly limit?: number;\n}\n\n// ============================================================================\n// AuditTrail\n// ============================================================================\n\n/**\n * Append-only audit trail for security pipeline decisions.\n * Events are bounded by MAX_EVENTS to prevent unbounded growth.\n */\n/**\n * Optional durable sink: receives every fully-formed event appended to the\n * trail, so security decisions can be mirrored to a persistent, hash-chained\n * store (see security/audit-bridge.ts). Default-off — when absent, the trail\n * behaves exactly as before (#3291).\n */\nexport type DurableAuditSink = (event: AuditEvent) => void;\n\nexport class AuditTrail {\n private events: AuditEvent[] = [];\n private nextId = 1;\n\n constructor(private readonly durableSink?: DurableAuditSink) {}\n\n /** Appends an event to the trail. Returns the assigned event ID. */\n append(event: Omit<AuditEvent, 'id' | 'timestamp'>): string {\n const id = `audit-${String(this.nextId++)}`;\n const fullEvent = {\n ...event,\n id,\n timestamp: getTimeProvider().nowIso(),\n } as AuditEvent;\n\n this.events.push(fullEvent);\n this.enforceLimit();\n\n // Mirror to the durable store when wired (#3291). Best-effort: a sink\n // failure must never break the in-memory security pipeline.\n if (this.durableSink !== undefined) {\n try {\n this.durableSink(fullEvent);\n } catch {\n // Sink implementations already swallow+log; this is belt-and-suspenders.\n }\n }\n\n return id;\n }\n\n /** Queries events matching the given filter. */\n query(filter: AuditQuery = {}): readonly AuditEvent[] {\n let results = this.events as readonly AuditEvent[];\n\n if (filter.type !== undefined) {\n results = results.filter((e) => e.type === filter.type);\n }\n\n if (filter.since !== undefined) {\n results = filterSince(results, filter.since);\n }\n\n if (filter.until !== undefined) {\n results = filterUntil(results, filter.until);\n }\n\n if (filter.trustTier !== undefined) {\n results = filterByTrustTier(results, filter.trustTier);\n }\n\n if (filter.actionType !== undefined) {\n results = filterByActionType(results, filter.actionType);\n }\n\n if (filter.actor !== undefined) {\n results = filterByActor(results, filter.actor);\n }\n\n if (filter.violationRule !== undefined) {\n results = filterByViolationRule(results, filter.violationRule);\n }\n\n const limit = filter.limit ?? results.length;\n return results.slice(-limit);\n }\n\n /** Returns the total number of events. */\n get size(): number {\n return this.events.length;\n }\n\n /** Clears all events. */\n clear(): void {\n this.events = [];\n }\n\n /** Enforces MAX_EVENTS bound. */\n private enforceLimit(): void {\n if (this.events.length > MAX_EVENTS) {\n this.events = this.events.slice(-MAX_EVENTS);\n }\n }\n}\n\n// ============================================================================\n// Filter Helpers\n// ============================================================================\n\nfunction filterSince(events: readonly AuditEvent[], since: string): readonly AuditEvent[] {\n const sinceTime = new Date(since).getTime();\n return events.filter((e) => new Date(e.timestamp).getTime() >= sinceTime);\n}\n\nfunction filterUntil(events: readonly AuditEvent[], until: string): readonly AuditEvent[] {\n const untilTime = new Date(until).getTime();\n return events.filter((e) => new Date(e.timestamp).getTime() <= untilTime);\n}\n\nfunction filterByTrustTier(events: readonly AuditEvent[], tier: TrustTier): readonly AuditEvent[] {\n return events.filter((e) => {\n if (e.type === 'trust_classification') return e.assignedTier === tier;\n if (e.type === 'policy_gate') return e.inputTrustTier === tier;\n if (e.type === 'reputation') return e.effectiveTier === tier;\n return true;\n });\n}\n\n/**\n * Narrow to events carrying the given `actionType` (#3197). Only PolicyGate and\n * Corroboration events have one; all others are excluded.\n */\nfunction filterByActionType(\n events: readonly AuditEvent[],\n actionType: AgentActionType\n): readonly AuditEvent[] {\n return events.filter(\n (e) => (e.type === 'policy_gate' || e.type === 'corroboration') && e.actionType === actionType\n );\n}\n\n/**\n * Narrow to events for the given actor (#3197), matched on `username`. Only\n * Trust-classification and Reputation events carry a username; others are\n * excluded so an actor filter never returns unrelated rows.\n */\nfunction filterByActor(events: readonly AuditEvent[], actor: string): readonly AuditEvent[] {\n return events.filter(\n (e) => (e.type === 'trust_classification' || e.type === 'reputation') && e.username === actor\n );\n}\n\n/**\n * Narrow to PolicyGate events whose `violationRules` include the given rule\n * name (#3197) — the security post-mortem \"who tripped rule X\" query.\n */\nfunction filterByViolationRule(events: readonly AuditEvent[], rule: string): readonly AuditEvent[] {\n return events.filter((e) => e.type === 'policy_gate' && e.violationRules.includes(rule));\n}\n\n// ============================================================================\n// Convenience Emitters\n// ============================================================================\n\n/**\n * Records a trust classification decision.\n */\nexport function emitTrustEvent(\n trail: AuditTrail,\n data: Omit<TrustClassificationEvent, 'id' | 'timestamp' | 'type' | 'component'>\n): string {\n return trail.append({\n type: 'trust_classification',\n component: 'trust-classifier',\n ...data,\n });\n}\n\n/**\n * Records a policy gate evaluation.\n */\nexport function emitPolicyEvent(\n trail: AuditTrail,\n data: Omit<PolicyGateEvent, 'id' | 'timestamp' | 'type' | 'component'>\n): string {\n return trail.append({\n type: 'policy_gate',\n component: 'policy-gate',\n ...data,\n });\n}\n\n/**\n * Records a PIPELINE-policy gate decision (#3710) — the dev-pipeline\n * consensus→execute seam. Distinct from {@link emitPolicyEvent} (the security\n * policy-gate path with an `AgentAction`): this carries `mode`/`ruleIds`/\n * `stageType` so the durable record distinguishes soak(warn) from enforce(block)\n * and is usable by the tune/readiness loop. ONE append per call.\n */\nexport function emitPipelinePolicyEvent(\n trail: AuditTrail,\n data: Omit<PolicyGateEvent, 'id' | 'timestamp' | 'type' | 'component' | 'actionType'>\n): string {\n return trail.append({\n type: 'policy_gate',\n component: 'pipeline-policy-evaluator',\n ...data,\n });\n}\n\n/** The pipeline-policy would-block rate over a window (#3727). */\nexport interface PolicyWouldBlockRate {\n /** Total pipeline-policy evaluations (the denominator — summary records). */\n readonly evaluations: number;\n /** Evaluations that had ≥1 violation (what enforce mode WOULD block). */\n readonly wouldBlock: number;\n /** `wouldBlock / evaluations`; 0 when there are no evaluations. */\n readonly rate: number;\n}\n\n/**\n * Compute the pipeline-policy would-block RATE from durable audit events (#3727)\n * — the read-side of the per-evaluation summary records, and the signal the\n * #3769-enforce soak-readiness gate needs. Denominator = per-evaluation SUMMARY\n * records (`recordKind === 'summary'`); numerator = summaries with\n * `violationCount > 0` (the would-block fraction, independent of warn/block mode).\n * Per-violation records (`recordKind === 'violation'`) are intentionally NOT\n * counted — counting them would double-count and break the denominator.\n */\nexport function computePolicyWouldBlockRate(events: readonly AuditEvent[]): PolicyWouldBlockRate {\n let evaluations = 0;\n let wouldBlock = 0;\n for (const e of events) {\n if (e.type !== 'policy_gate' || e.recordKind !== 'summary') continue;\n evaluations += 1;\n if ((e.violationCount ?? 0) > 0) wouldBlock += 1;\n }\n return { evaluations, wouldBlock, rate: evaluations > 0 ? wouldBlock / evaluations : 0 };\n}\n\n/**\n * Records a corroboration validation.\n */\nexport function emitCorroborationEvent(\n trail: AuditTrail,\n data: Omit<CorroborationEvent, 'id' | 'timestamp' | 'type' | 'component'>\n): string {\n return trail.append({\n type: 'corroboration',\n component: 'corroboration-validator',\n ...data,\n });\n}\n\n/**\n * Records a reputation assessment.\n */\nexport function emitReputationEvent(\n trail: AuditTrail,\n data: Omit<ReputationEvent, 'id' | 'timestamp' | 'type' | 'component'>\n): string {\n return trail.append({\n type: 'reputation',\n component: 'reputation-model',\n ...data,\n });\n}\n\n/**\n * Records an input sanitization result.\n */\nexport function emitSanitizationEvent(\n trail: AuditTrail,\n data: Omit<SanitizationEvent, 'id' | 'timestamp' | 'type' | 'component'>\n): string {\n return trail.append({\n type: 'sanitization',\n component: 'input-sanitizer',\n ...data,\n });\n}\n\n/**\n * Records a graph execution lifecycle event.\n */\nexport function emitGraphExecutionEvent(\n trail: AuditTrail,\n data: Omit<GraphExecutionAuditEvent, 'id' | 'timestamp' | 'type' | 'component'>\n): string {\n return trail.append({\n type: 'graph_execution',\n component: 'graph-executor',\n ...data,\n });\n}\n\n/**\n * Creates an onEvent callback that bridges graph events to the audit trail.\n * Pass the returned function as `onEvent` in GraphExecuteOptions.\n *\n * @example\n * const trail = createAuditTrail();\n * await executeGraph(graph, inputs, { onEvent: createGraphAuditBridge(trail) });\n */\nexport function createGraphAuditBridge(\n trail: AuditTrail\n): (event: { readonly type: string; readonly [key: string]: unknown }) => void {\n return (event) => {\n const nodeId = typeof event['nodeId'] === 'string' ? event['nodeId'] : undefined;\n const stepNumber = typeof event['stepNumber'] === 'number' ? event['stepNumber'] : 0;\n emitGraphExecutionEvent(trail, {\n graphEvent: event.type,\n ...(nodeId !== undefined ? { nodeId } : {}),\n stepNumber,\n detail: formatGraphEventDetail(event),\n });\n };\n}\n\n/** Formats a brief detail string from a graph event. */\nfunction formatGraphEventDetail(event: {\n readonly type: string;\n readonly [key: string]: unknown;\n}): string {\n switch (event.type) {\n case 'node_started':\n return `Node ${String(event['nodeId'])} starting`;\n case 'node_completed':\n return `Node ${String(event['nodeId'])} completed in ${String(event['durationMs'])}ms`;\n case 'node_error':\n return `Node ${String(event['nodeId'])} failed: ${String(event['error'])}`;\n case 'state_updated':\n return `State updated: ${String(event['updatedKeys'])}`;\n case 'step_completed':\n return `Step ${String(event['stepNumber'])}: ${String(event['nodesExecuted'])} nodes`;\n case 'execution_complete':\n return `Complete: ${String(event['totalSteps'])} steps, ${String(event['durationMs'])}ms`;\n default:\n return event.type;\n }\n}\n\n/**\n * Creates a new AuditTrail instance. Pass a {@link DurableAuditSink} (e.g. from\n * `createDurableAuditSink(auditLogger)`) to mirror appended security decisions\n * to a durable, hash-chained store (#3291). Default: in-memory only.\n */\nexport function createAuditTrail(durableSink?: DurableAuditSink): AuditTrail {\n return new AuditTrail(durableSink);\n}\n","/**\n * nexus-agents/security - Corroboration Validator\n *\n * Validates that agent decisions are backed by sufficient evidence from\n * authoritative sources. Each action type has specific corroboration\n * requirements (e.g., closing issues requires CI pass or maintainer comment).\n *\n * Defense layer 3 of the three-layer hardening architecture.\n * See: docs/architecture/UNTRUSTED_INPUT_HARDENING.md\n *\n * @module security/corroboration-validator\n * (Source: Issue #818, #823 — Phase 2: Corroboration Validator)\n */\n\nimport type { AgentAction, AgentActionType, SourceCitation } from './action-schema.js';\nimport type { TrustTier } from './trust-types.js';\nimport { TRUST_TIER_NUMERIC } from './trust-types.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Result of corroboration validation.\n */\nexport interface CorroborationResult {\n /** Whether corroboration requirements are satisfied. */\n readonly satisfied: boolean;\n /** Sources that contributed to corroboration. */\n readonly corroboratingSources: readonly SourceCitation[];\n /** Missing corroboration requirements (empty when satisfied). */\n readonly missing: readonly string[];\n /** Action type that was validated. */\n readonly actionType: AgentActionType;\n}\n\n/**\n * Rule defining what corroboration an action requires.\n */\nexport interface CorroborationRule {\n /** Human-readable description of what's required. */\n readonly description: string;\n /** Predicate: does this set of sources satisfy the requirement? */\n readonly isSatisfied: (sources: readonly SourceCitation[]) => boolean;\n}\n\n// ============================================================================\n// Source Helpers\n// ============================================================================\n\n/** Check if sources include a passing CI result. */\nfunction hasCIPass(sources: readonly SourceCitation[]): boolean {\n return sources.some((s) => s.type === 'ciResult' && s.status === 'pass');\n}\n\n/** Check if sources include a maintainer command. */\nfunction hasMaintainerCommand(sources: readonly SourceCitation[]): boolean {\n return sources.some((s) => s.type === 'maintainerCommand');\n}\n\n/** Check if sources include a Tier 1 issue comment. */\nfunction hasTier1Comment(sources: readonly SourceCitation[]): boolean {\n return sources.some((s) => s.type === 'issueComment' && s.authorTrustTier === '1');\n}\n\n/** Check if sources include a repo file reference. */\nfunction hasRepoFileRef(sources: readonly SourceCitation[]): boolean {\n return sources.some((s) => s.type === 'repoFile');\n}\n\n/** Check if sources include a repo file with line reference. */\nfunction hasCodeLevelEvidence(sources: readonly SourceCitation[]): boolean {\n return sources.some((s) => s.type === 'repoFile' && s.line !== undefined);\n}\n\n/** Check if sources include a policy document reference. */\nfunction hasPolicyDocRef(sources: readonly SourceCitation[]): boolean {\n return sources.some((s) => s.type === 'policyDoc');\n}\n\n/** Check if at least one source meets a minimum trust tier. */\nfunction hasSourceAtTier(sources: readonly SourceCitation[], maxTier: TrustTier): boolean {\n const maxNumeric = TRUST_TIER_NUMERIC[maxTier];\n return sources.some((s) => {\n if (s.type === 'issueComment') {\n return TRUST_TIER_NUMERIC[s.authorTrustTier] <= maxNumeric;\n }\n // Repo files, CI results, policy docs, maintainer commands = Tier 1\n return true;\n });\n}\n\n// ============================================================================\n// Per-Action Corroboration Rules\n// ============================================================================\n\n/**\n * Corroboration rules for each action type.\n * See CLAUDE.md \"Corroboration Requirements\" table.\n */\nconst ACTION_CORROBORATION_RULES: Readonly<Record<AgentActionType, readonly CorroborationRule[]>> =\n {\n SummarizeIssue: [\n {\n description: 'At least one Tier 1/2 source',\n isSatisfied: (s) => hasSourceAtTier(s, '2'),\n },\n ],\n ProposeLabels: [\n {\n description: 'Keyword match in issue body (repo file) OR maintainer instruction',\n isSatisfied: (s) => hasRepoFileRef(s) || hasMaintainerCommand(s) || hasPolicyDocRef(s),\n },\n ],\n DraftReply: [\n {\n description: 'At least one Tier 1 source citation',\n isSatisfied: (s) =>\n hasRepoFileRef(s) ||\n hasCIPass(s) ||\n hasMaintainerCommand(s) ||\n hasPolicyDocRef(s) ||\n hasTier1Comment(s),\n },\n ],\n GeneratePatchPlan: [\n {\n description: 'Failing test OR bug reproduction steps (code-level evidence)',\n isSatisfied: (s) => hasCodeLevelEvidence(s) || hasCIPass(s),\n },\n {\n description: 'Maintainer corroboration',\n isSatisfied: (s) => hasMaintainerCommand(s) || hasTier1Comment(s),\n },\n ],\n ClassifyIssue: [\n {\n description: 'At least one source citation',\n isSatisfied: (s) => s.length > 0,\n },\n ],\n IdentifyDuplicates: [\n {\n description: 'At least one source citation',\n isSatisfied: (s) => s.length > 0,\n },\n ],\n RequestHumanApproval: [],\n RefuseAction: [],\n HandoffMessage: [\n {\n description: 'At least one source citation for trust tier propagation',\n isSatisfied: (s) => s.length > 0,\n },\n ],\n };\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Validate that an agent action has sufficient corroboration from\n * authoritative sources.\n *\n * @param action - The validated AgentAction to check.\n * @returns CorroborationResult indicating whether requirements are met.\n */\nexport function validateCorroboration(action: AgentAction): CorroborationResult {\n const rules = ACTION_CORROBORATION_RULES[action.type];\n const sources: readonly SourceCitation[] = 'sources' in action ? action.sources : [];\n\n if (rules.length === 0) {\n return {\n satisfied: true,\n corroboratingSources: sources,\n missing: [],\n actionType: action.type,\n };\n }\n\n const missing: string[] = [];\n const corroborating: SourceCitation[] = [];\n\n for (const rule of rules) {\n if (rule.isSatisfied(sources)) {\n for (const s of sources) {\n if (!corroborating.includes(s)) {\n corroborating.push(s);\n }\n }\n } else {\n missing.push(rule.description);\n }\n }\n\n return {\n satisfied: missing.length === 0,\n corroboratingSources: corroborating,\n missing,\n actionType: action.type,\n };\n}\n\n/**\n * Get the corroboration rules for an action type.\n * Useful for displaying requirements to users.\n */\nexport function getCorroborationRules(actionType: AgentActionType): readonly CorroborationRule[] {\n return ACTION_CORROBORATION_RULES[actionType];\n}\n","/**\n * nexus-agents/scm - URL parsers\n *\n * Pure parsers for GitHub PR and issue URLs. Lifted from\n * `dogfooding/github-client.ts` as part of the #2553 consolidation —\n * URL parsing has no transport-layer dependency, so it belongs in the\n * canonical SCM module alongside the rest of the GitHub surface.\n *\n * @module scm/url-parsers\n */\n\nimport type { Result } from '../core/index.js';\nimport { ok, err } from '../core/index.js';\n\n/**\n * Parses a PR URL into owner, repo, and number. Accepts:\n *\n * - `https://github.com/owner/repo/pull/123`\n * - `https://www.github.com/owner/repo/pull/123`\n * - `owner/repo#123`\n * - `owner/repo/pull/123`\n */\nexport function parsePRUrl(url: string): Result<\n {\n owner: string;\n repo: string;\n prNumber: number;\n },\n Error\n> {\n const httpPattern = /github\\.com\\/([^/]+)\\/([^/]+)\\/pull\\/(\\d+)/;\n const shortPattern = /^([^/]+)\\/([^/#]+)(?:#|\\/pull\\/)(\\d+)$/;\n\n const match = httpPattern.exec(url) ?? shortPattern.exec(url);\n\n if (match === null) {\n return err(new Error(`Invalid PR URL format: ${url}`));\n }\n\n const owner = match[1];\n const repo = match[2];\n const numberStr = match[3];\n\n if (owner === undefined || repo === undefined || numberStr === undefined) {\n return err(new Error(`Invalid PR URL format: ${url}`));\n }\n\n const prNumber = parseInt(numberStr, 10);\n\n if (isNaN(prNumber)) {\n return err(new Error(`Invalid PR URL format: ${url}`));\n }\n\n return ok({ owner, repo, prNumber });\n}\n\n/**\n * Parses an issue URL into owner, repo, and number. Accepts:\n *\n * - `https://github.com/owner/repo/issues/123`\n * - `owner/repo#123`\n */\nexport function parseIssueUrl(url: string): Result<\n {\n owner: string;\n repo: string;\n issueNumber: number;\n },\n Error\n> {\n const httpPattern = /github\\.com\\/([^/]+)\\/([^/]+)\\/issues\\/(\\d+)/;\n const shortPattern = /^([^/]+)\\/([^/#]+)#(\\d+)$/;\n\n const match = httpPattern.exec(url) ?? shortPattern.exec(url);\n\n if (match === null) {\n return err(new Error(`Invalid issue URL format: ${url}`));\n }\n\n const owner = match[1];\n const repo = match[2];\n const numberStr = match[3];\n\n if (owner === undefined || repo === undefined || numberStr === undefined) {\n return err(new Error(`Invalid issue URL format: ${url}`));\n }\n\n const issueNumber = parseInt(numberStr, 10);\n\n if (isNaN(issueNumber)) {\n return err(new Error(`Invalid issue URL format: ${url}`));\n }\n\n return ok({ owner, repo, issueNumber });\n}\n","/**\n * nexus-agents/scm - GitHub Provider Trait Implementations\n *\n * Implements IScmReviewer and IScmUserInfo trait interfaces for GitHub.\n * Uses `gh api` for REST API access to get detailed data.\n *\n * @module scm/github-provider-traits\n * (Source: Issue #1136 — Centralized SCM Provider Module)\n */\n\nimport type { Result } from '../core/index.js';\nimport { ok, err, createLogger } from '../core/index.js';\nimport type {\n IScmReviewer,\n IScmUserInfo,\n ScmPullRequestDetail,\n ScmIssueDetail,\n ScmCommentDetail,\n ScmReviewDecision,\n ScmUserMetadata,\n ScmFileChange,\n} from './types.js';\nimport { ScmError } from './types.js';\nimport { GitHubProvider } from './github-provider.js';\nimport { CLI_SUBPROCESS_TIMEOUTS } from '../config/timeouts.js';\n\nconst logger = createLogger({ component: 'GitHubProviderTraits' });\n\n// ============================================================================\n// gh API JSON types (internal)\n// ============================================================================\n\ninterface GhApiPrJson {\n number: number;\n title: string;\n body: string | null;\n html_url: string;\n user: { login: string };\n author_association: string;\n base: { ref: string };\n head: { ref: string; sha: string };\n draft: boolean;\n labels: Array<{ name: string }>;\n additions: number;\n deletions: number;\n}\n\ninterface GhApiFileJson {\n filename: string;\n status: string;\n additions: number;\n deletions: number;\n patch?: string;\n previous_filename?: string;\n}\n\ninterface GhApiIssueJson {\n number: number;\n title: string;\n body: string | null;\n user: { login: string };\n author_association: string;\n state: string;\n html_url: string;\n labels: Array<{ name: string }>;\n created_at: string;\n}\n\ninterface GhApiCommentJson {\n id: number;\n body: string;\n user: { login: string };\n author_association: string;\n created_at: string;\n}\n\ninterface GhApiUserJson {\n login: string;\n name: string | null;\n company: string | null;\n followers: number;\n following: number;\n public_repos: number;\n created_at: string;\n}\n\n// ============================================================================\n// gh API executor\n// ============================================================================\n\n/**\n * Resolves a GitHub token from env vars or `gh auth token`.\n * Caches the result to avoid repeated subprocess calls.\n */\nlet cachedGhToken: string | undefined | null = null;\nlet ghTokenPromise: Promise<string | undefined> | undefined;\n\n/** Reset the cached token (for testing). */\nexport function resetGhTokenCache(): void {\n cachedGhToken = null;\n ghTokenPromise = undefined;\n}\n\nasync function resolveGhToken(): Promise<string | undefined> {\n if (cachedGhToken !== null) return cachedGhToken;\n\n ghTokenPromise ??= resolveGhTokenImpl().finally(() => {\n ghTokenPromise = undefined;\n });\n return ghTokenPromise;\n}\n\nasync function resolveGhTokenImpl(): Promise<string | undefined> {\n const envToken = process.env['GITHUB_TOKEN'] ?? process.env['GH_TOKEN'];\n if (envToken !== undefined && envToken.length > 0) {\n cachedGhToken = envToken;\n return envToken;\n }\n\n try {\n const { execFile } = await import('node:child_process');\n const { promisify } = await import('node:util');\n const exec = promisify(execFile);\n const { stdout } = await exec('gh', ['auth', 'token'], { timeout: 5_000 });\n const token = stdout.trim();\n cachedGhToken = token.length > 0 ? token : undefined;\n } catch {\n cachedGhToken = undefined;\n }\n return cachedGhToken;\n}\n\nasync function execGhApi(endpoint: string, method?: string): Promise<Result<string, ScmError>> {\n const { execFile } = await import('node:child_process');\n const { promisify } = await import('node:util');\n const exec = promisify(execFile);\n\n const args = ['api', endpoint];\n if (method !== undefined) args.push('--method', method);\n\n // Inject token into subprocess environment to prevent keyring access failures\n const token = await resolveGhToken();\n const env = token !== undefined ? { ...process.env, GH_TOKEN: token } : undefined;\n\n try {\n const { stdout } = await exec('gh', args, {\n maxBuffer: 10 * 1024 * 1024,\n timeout: CLI_SUBPROCESS_TIMEOUTS.ghCommandMs,\n ...(env !== undefined ? { env } : {}),\n });\n return ok(stdout.trim());\n } catch (error) {\n const execError = error as { message: string; stderr?: string };\n return err(\n new ScmError(`gh api failed: ${execError.message}`, 'github', undefined, {\n endpoint,\n stderr: execError.stderr,\n })\n );\n }\n}\n\n// ============================================================================\n// Mappers\n// ============================================================================\n\nfunction mapFileChange(raw: GhApiFileJson): ScmFileChange {\n const statusMap: Record<string, ScmFileChange['status']> = {\n added: 'added',\n removed: 'removed',\n modified: 'modified',\n renamed: 'renamed',\n copied: 'copied',\n };\n return {\n filename: raw.filename,\n status: statusMap[raw.status] ?? 'modified',\n additions: raw.additions,\n deletions: raw.deletions,\n ...(raw.patch !== undefined ? { patch: raw.patch } : {}),\n ...(raw.previous_filename !== undefined ? { previousFilename: raw.previous_filename } : {}),\n };\n}\n\n// ============================================================================\n// GitHubReviewer — implements IScmReviewer\n// ============================================================================\n\n/**\n * GitHub-specific reviewer that adds PR detail and review capabilities\n * to a GitHubProvider. Implements IScmReviewer trait.\n *\n * @example\n * ```typescript\n * const provider = createGitHubProvider('owner/repo');\n * const reviewer = new GitHubReviewer(provider);\n * const detail = await reviewer.getPullRequestDetail(42);\n * ```\n */\nexport class GitHubReviewer implements IScmReviewer {\n constructor(private readonly provider: GitHubProvider) {}\n\n async getPullRequestDetail(prNumber: number): Promise<Result<ScmPullRequestDetail, ScmError>> {\n const repo = this.provider.repo;\n logger.debug('Getting PR detail', { repo, prNumber });\n\n const prResult = await execGhApi(`repos/${repo}/pulls/${String(prNumber)}`);\n if (!prResult.ok) return prResult;\n\n const filesResult = await execGhApi(`repos/${repo}/pulls/${String(prNumber)}/files`);\n if (!filesResult.ok) return filesResult;\n\n try {\n const pr = JSON.parse(prResult.value) as GhApiPrJson;\n const files = JSON.parse(filesResult.value) as GhApiFileJson[];\n\n return ok({\n number: pr.number,\n title: pr.title,\n body: pr.body ?? '',\n author: pr.user.login,\n base: pr.base.ref,\n head: pr.head.ref,\n url: pr.html_url,\n draft: pr.draft,\n authorAssociation: pr.author_association,\n labels: pr.labels.map((l) => l.name),\n files: files.map(mapFileChange),\n additions: pr.additions,\n deletions: pr.deletions,\n headSha: pr.head.sha,\n });\n } catch {\n return err(new ScmError('Failed to parse PR detail JSON', 'github'));\n }\n }\n\n async createReview(\n prNumber: number,\n body: string,\n decision: ScmReviewDecision\n ): Promise<Result<void, ScmError>> {\n const repo = this.provider.repo;\n const eventMap: Record<ScmReviewDecision, string> = {\n approve: 'APPROVE',\n request_changes: 'REQUEST_CHANGES',\n comment: 'COMMENT',\n };\n\n logger.info('Creating review', { repo, prNumber, decision });\n\n const { execFile } = await import('node:child_process');\n const { promisify } = await import('node:util');\n const exec = promisify(execFile);\n\n try {\n await exec(\n 'gh',\n [\n 'api',\n `repos/${repo}/pulls/${String(prNumber)}/reviews`,\n '--method',\n 'POST',\n '-f',\n `body=${body}`,\n '-f',\n `event=${eventMap[decision]}`,\n ],\n { maxBuffer: 10 * 1024 * 1024, timeout: CLI_SUBPROCESS_TIMEOUTS.ghCommandMs }\n );\n return ok(undefined);\n } catch (error) {\n const execError = error as { message: string };\n return err(new ScmError(`Failed to create review: ${execError.message}`, 'github'));\n }\n }\n\n async getIssueDetail(issueNumber: number): Promise<Result<ScmIssueDetail, ScmError>> {\n const repo = this.provider.repo;\n logger.debug('Getting issue detail', { repo, issueNumber });\n\n const result = await execGhApi(`repos/${repo}/issues/${String(issueNumber)}`);\n if (!result.ok) return result;\n\n try {\n const raw = JSON.parse(result.value) as GhApiIssueJson;\n return ok({\n number: raw.number,\n title: raw.title,\n body: raw.body ?? '',\n labels: raw.labels.map((l) => l.name),\n author: raw.user.login,\n createdAt: raw.created_at,\n authorAssociation: raw.author_association,\n state: raw.state,\n url: raw.html_url,\n });\n } catch {\n return err(new ScmError('Failed to parse issue detail JSON', 'github'));\n }\n }\n\n async listCommentDetails(\n issueNumber: number\n ): Promise<Result<readonly ScmCommentDetail[], ScmError>> {\n const repo = this.provider.repo;\n logger.debug('Listing comment details', { repo, issueNumber });\n\n const result = await execGhApi(`repos/${repo}/issues/${String(issueNumber)}/comments`);\n if (!result.ok) return result;\n\n try {\n const comments = JSON.parse(result.value) as GhApiCommentJson[];\n return ok(\n comments.map((c) => ({\n id: c.id,\n body: c.body,\n author: c.user.login,\n createdAt: c.created_at,\n authorAssociation: c.author_association,\n }))\n );\n } catch {\n return err(new ScmError('Failed to parse comment details JSON', 'github'));\n }\n }\n}\n\n// ============================================================================\n// GitHubUserInfo — implements IScmUserInfo\n// ============================================================================\n\n/**\n * GitHub-specific user info provider. Implements IScmUserInfo trait.\n */\nexport class GitHubUserInfo implements IScmUserInfo {\n async fetchUserMetadata(username: string): Promise<Result<ScmUserMetadata, ScmError>> {\n logger.debug('Fetching user metadata', { username });\n\n const result = await execGhApi(`users/${username}`);\n if (!result.ok) return result;\n\n try {\n const raw = JSON.parse(result.value) as GhApiUserJson;\n return ok({\n login: raw.login,\n name: raw.name,\n company: raw.company,\n followers: raw.followers,\n following: raw.following,\n publicRepos: raw.public_repos,\n createdAt: raw.created_at,\n });\n } catch {\n return err(new ScmError('Failed to parse user metadata JSON', 'github'));\n }\n }\n}\n\n// ============================================================================\n// Factory — compose provider with traits\n// ============================================================================\n\n/**\n * Creates a full-capability GitHub provider with all traits.\n *\n * Returns an object that implements IScmProvider & IScmReviewer & IScmUserInfo.\n * Consumers can narrow the type to only the traits they need.\n *\n * @example\n * ```typescript\n * const provider = createFullGitHubProvider('owner/repo');\n * // Use as ReviewCapableProvider\n * const detail = await provider.getPullRequestDetail(42);\n * // Use as IScmUserInfo\n * const user = await provider.fetchUserMetadata('octocat');\n * ```\n */\nexport function createFullGitHubProvider(\n repo: string\n): GitHubProvider & IScmReviewer & IScmUserInfo {\n const base = new GitHubProvider(repo);\n const reviewer = new GitHubReviewer(base);\n const userInfo = new GitHubUserInfo();\n\n // Compose all trait methods onto the provider\n return Object.assign(base, {\n getPullRequestDetail: reviewer.getPullRequestDetail.bind(reviewer),\n createReview: reviewer.createReview.bind(reviewer),\n getIssueDetail: reviewer.getIssueDetail.bind(reviewer),\n listCommentDetails: reviewer.listCommentDetails.bind(reviewer),\n fetchUserMetadata: userInfo.fetchUserMetadata.bind(userInfo),\n });\n}\n","/**\n * nexus-agents/dogfooding - Issue Triage Types\n *\n * Type definitions for automated GitHub issue triage using\n * the security pipeline (trust classification, corroboration,\n * reputation model).\n *\n * @module dogfooding/issue-triage-types\n * (Source: Issue #828 — Wire remaining security modules)\n */\n\nimport { z } from 'zod';\n\n// ============================================================================\n// Issue Metadata\n// ============================================================================\n\n/**\n * GitHub issue metadata from the API.\n */\nexport interface IssueMetadata {\n /** Issue number */\n readonly number: number;\n /** Issue title */\n readonly title: string;\n /** Issue body/description */\n readonly body: string;\n /** Author username */\n readonly author: string;\n /** GitHub API author_association (e.g., 'OWNER', 'COLLABORATOR', 'NONE') */\n readonly authorAssociation: string;\n /** Repository owner */\n readonly owner: string;\n /** Repository name */\n readonly repo: string;\n /** Issue URL */\n readonly url: string;\n /** Issue state ('open' | 'closed') */\n readonly state: string;\n /** Issue labels */\n readonly labels: readonly string[];\n /** Creation timestamp (ISO 8601) */\n readonly createdAt: string;\n}\n\n/**\n * GitHub issue comment from the API.\n */\nexport interface IssueComment {\n /** Comment ID */\n readonly id: number;\n /** Comment body */\n readonly body: string;\n /** Author username */\n readonly author: string;\n /** GitHub API author_association */\n readonly authorAssociation: string;\n /** Creation timestamp (ISO 8601) */\n readonly createdAt: string;\n}\n\n// ============================================================================\n// Issue Classification\n// ============================================================================\n\n/**\n * Issue category determined by keyword-based classification.\n */\nexport type IssueCategory =\n | 'bug'\n | 'feature'\n | 'question'\n | 'documentation'\n | 'security'\n | 'performance';\n\n/**\n * Display names for issue categories.\n */\nexport const CATEGORY_DISPLAY_NAMES: Record<IssueCategory, string> = {\n bug: 'Bug Report',\n feature: 'Feature Request',\n question: 'Question',\n documentation: 'Documentation',\n security: 'Security',\n performance: 'Performance',\n};\n\n/**\n * Emoji for issue categories (GitHub markdown).\n */\nexport const CATEGORY_EMOJI: Record<IssueCategory, string> = {\n bug: ':bug:',\n feature: ':sparkles:',\n question: ':question:',\n documentation: ':books:',\n security: ':lock:',\n performance: ':zap:',\n};\n\n// ============================================================================\n// Triage Configuration\n// ============================================================================\n\n/**\n * Configuration for issue triage.\n */\nexport interface IssueTriageConfig {\n /** Whether to run in dry-run mode (no GitHub mutations). Default: true */\n readonly dryRun: boolean;\n /** GitHub token for API access */\n readonly githubToken?: string | undefined;\n /** Maximum comments to fetch per issue */\n readonly maxComments: number;\n /** Whether to use reputation model for trust assessment */\n readonly enableReputation: boolean;\n}\n\n/**\n * Default issue triage configuration.\n * Read-only by default — proposes actions without executing them.\n */\nexport const DEFAULT_ISSUE_TRIAGE_CONFIG: IssueTriageConfig = {\n dryRun: true,\n maxComments: 50,\n enableReputation: true,\n};\n\n/**\n * Zod schema for issue triage configuration.\n */\nexport const IssueTriageConfigSchema = z.object({\n dryRun: z.boolean().default(true),\n githubToken: z.string().optional(),\n maxComments: z.number().int().min(1).max(100).default(50),\n enableReputation: z.boolean().default(true),\n});\n\n// ============================================================================\n// Proposed Actions\n// ============================================================================\n\n/**\n * A proposed action from the triage pipeline.\n * All actions are validated through the security pipeline before output.\n */\nexport interface ProposedAction {\n /** Action type (matches AgentActionType from security/action-schema) */\n readonly type: string;\n /** Human-readable description of the proposed action */\n readonly description: string;\n /** Whether this action was approved by the policy gate */\n readonly policyApproved: boolean;\n /** Whether corroboration requirements were satisfied */\n readonly corroborated: boolean;\n /** Details specific to the action type */\n readonly details: Record<string, unknown>;\n}\n\n// ============================================================================\n// Trust Assessment\n// ============================================================================\n\n/**\n * Trust assessment summary for the triage result.\n */\nexport interface TrustAssessment {\n /** Author's trust tier (1-4) */\n readonly trustTier: string;\n /** Author's GitHub role */\n readonly userRole: string;\n /** Whether the author is on the maintainer allowlist */\n readonly isAllowlisted: boolean;\n /** Reputation score (0-100) if reputation model is enabled */\n readonly reputationScore?: number | undefined;\n /** Suspicious signals detected */\n readonly suspiciousSignals: readonly string[];\n /** Whether the author is flagged as suspicious */\n readonly isSuspicious: boolean;\n /**\n * Tier the policy gate ACTUALLY enforced (#3122). Equals `trustTier` under\n * `audit`/`off`; equals `reputationReconciledTier` under `enforce`. This is\n * the tier `proposedActions[].policyApproved` was decided against.\n */\n readonly enforcedTrustTier?: string | undefined;\n /**\n * Tier reputation reconciliation computed — what `enforce` mode WOULD gate on\n * (#3122). May exceed `trustTier` (more restrictive) when reputation demotes.\n * Under `audit`/`off` this is reported for telemetry but NOT enforced — read\n * `enforcedTrustTier` for the tier actually in effect.\n */\n readonly reputationReconciledTier?: string | undefined;\n /** Reputation-gating rollout mode applied: `off` | `audit` | `enforce` (#3122). */\n readonly gatingMode?: string | undefined;\n}\n\n// ============================================================================\n// Triage Result\n// ============================================================================\n\n/**\n * Complete triage result for a GitHub issue.\n */\nexport interface IssueTriageResult {\n /** Issue number */\n readonly issueNumber: number;\n /** Repository (owner/repo) */\n readonly repository: string;\n /** Proposed actions (validated through security pipeline) */\n readonly proposedActions: readonly ProposedAction[];\n /** Trust assessment of the issue author */\n readonly trustAssessment: TrustAssessment;\n /** Detected issue category */\n readonly category: IssueCategory;\n /** Category confidence (0-1) */\n readonly categoryConfidence: number;\n /** Total execution time in ms */\n readonly totalDurationMs: number;\n /** Timestamp of triage (ISO 8601) */\n readonly timestamp: string;\n}\n","/**\n * nexus-agents/dogfooding - Issue Triage Helpers\n *\n * Pure helper functions for issue classification, label extraction,\n * and result formatting. No side effects or API calls.\n *\n * @module dogfooding/issue-triage-helpers\n * (Source: Issue #828 — Wire remaining security modules)\n */\n\nimport type { IssueCategory, IssueTriageResult, ProposedAction } from './issue-triage-types.js';\nimport { CATEGORY_DISPLAY_NAMES, CATEGORY_EMOJI } from './issue-triage-types.js';\n\n// ============================================================================\n// Issue Classification\n// ============================================================================\n\n/**\n * Keyword sets for each issue category.\n * Lower-cased for case-insensitive matching.\n */\nconst CATEGORY_KEYWORDS: Record<IssueCategory, readonly string[]> = {\n bug: ['bug', 'error', 'crash', 'broken', 'fix', 'fail', 'issue', 'wrong', 'unexpected'],\n feature: ['feature', 'request', 'enhancement', 'proposal', 'add', 'support', 'implement'],\n question: ['question', 'how to', 'help', 'confused', 'explain', 'documentation'],\n documentation: ['docs', 'documentation', 'readme', 'typo', 'example', 'guide'],\n security: ['security', 'vulnerability', 'cve', 'exploit', 'injection', 'xss', 'csrf'],\n performance: ['performance', 'slow', 'memory', 'leak', 'optimize', 'latency', 'timeout'],\n};\n\n/**\n * Classifies an issue by matching keywords in the title and body.\n * Returns the category with the highest keyword match count.\n *\n * @param title - Issue title\n * @param body - Issue body\n * @returns Tuple of [category, confidence]\n */\nexport function categorizeIssue(title: string, body: string): [IssueCategory, number] {\n const text = `${title} ${body}`.toLowerCase();\n const scores: Record<IssueCategory, number> = {\n bug: 0,\n feature: 0,\n question: 0,\n documentation: 0,\n security: 0,\n performance: 0,\n };\n\n let totalMatches = 0;\n\n for (const [category, keywords] of Object.entries(CATEGORY_KEYWORDS)) {\n for (const keyword of keywords) {\n if (text.includes(keyword)) {\n scores[category as IssueCategory]++;\n totalMatches++;\n }\n }\n }\n\n // Find category with highest score\n let bestCategory: IssueCategory = 'bug';\n let bestScore = 0;\n for (const [category, score] of Object.entries(scores)) {\n if (score > bestScore) {\n bestScore = score;\n bestCategory = category as IssueCategory;\n }\n }\n\n // Confidence: ratio of best score to total matches, minimum 0.1\n const confidence = totalMatches > 0 ? Math.min(bestScore / totalMatches, 1) : 0.1;\n\n return [bestCategory, Math.round(confidence * 100) / 100];\n}\n\n// ============================================================================\n// Label Extraction\n// ============================================================================\n\n/**\n * Common label patterns that can be extracted from issue text.\n */\nconst LABEL_HINTS: ReadonlyMap<string, string> = new Map([\n ['bug', 'bug'],\n ['feature request', 'enhancement'],\n ['enhancement', 'enhancement'],\n ['breaking change', 'breaking-change'],\n ['documentation', 'documentation'],\n ['help wanted', 'help wanted'],\n ['good first issue', 'good first issue'],\n ['security', 'security'],\n ['performance', 'performance'],\n ['regression', 'regression'],\n]);\n\n/**\n * Extracts suggested labels from issue title and body text.\n *\n * @param title - Issue title\n * @param body - Issue body\n * @returns Array of suggested label strings (max 5)\n */\nexport function extractLabelsFromBody(title: string, body: string): string[] {\n const text = `${title} ${body}`.toLowerCase();\n const labels: string[] = [];\n\n for (const [pattern, label] of LABEL_HINTS) {\n if (text.includes(pattern) && !labels.includes(label)) {\n labels.push(label);\n }\n }\n\n return labels.slice(0, 5);\n}\n\n// ============================================================================\n// Result Formatting\n// ============================================================================\n\n/**\n * Formats a triage result as a GitHub markdown comment.\n *\n * @param result - The complete triage result\n * @returns Formatted markdown string\n */\nexport function formatTriageComment(result: IssueTriageResult): string {\n const emoji = CATEGORY_EMOJI[result.category];\n const categoryName = CATEGORY_DISPLAY_NAMES[result.category];\n const lines: string[] = [];\n\n lines.push(`## ${emoji} Issue Triage: ${categoryName}`);\n lines.push('');\n lines.push(\n `**Category:** ${categoryName} (${String(Math.round(result.categoryConfidence * 100))}% confidence)`\n );\n lines.push(\n `**Trust Tier:** ${result.trustAssessment.trustTier} (${result.trustAssessment.userRole})`\n );\n\n if (result.trustAssessment.reputationScore !== undefined) {\n lines.push(`**Reputation Score:** ${String(result.trustAssessment.reputationScore)}/100`);\n }\n\n if (result.trustAssessment.isSuspicious) {\n lines.push('');\n lines.push(':warning: **Suspicious signals detected:**');\n for (const signal of result.trustAssessment.suspiciousSignals) {\n lines.push(`- ${signal}`);\n }\n }\n\n if (result.proposedActions.length > 0) {\n lines.push('');\n lines.push('### Proposed Actions');\n lines.push('');\n for (const action of result.proposedActions) {\n const status = formatActionStatus(action);\n lines.push(`- ${status} **${action.type}**: ${action.description}`);\n }\n }\n\n lines.push('');\n lines.push(`---`);\n lines.push(`_Triage completed in ${String(result.totalDurationMs)}ms_`);\n\n return lines.join('\\n');\n}\n\n/**\n * Formats the policy/corroboration status of an action.\n */\nfunction formatActionStatus(action: ProposedAction): string {\n if (action.policyApproved && action.corroborated) return ':white_check_mark:';\n if (action.policyApproved && !action.corroborated) return ':yellow_circle:';\n return ':no_entry:';\n}\n","/**\n * nexus-agents/dogfooding - Issue Triage Processor\n *\n * Deterministic GitHub issue triage using the full security pipeline:\n * - Input sanitization (input-sanitizer.ts)\n * - Trust classification (trust-classifier.ts)\n * - Reputation assessment (reputation-model.ts) [NEW — #828]\n * - Typed agent actions (action-schema.ts)\n * - Policy gate validation (policy-gate.ts)\n * - Corroboration validation (corroboration-validator.ts) [NEW — #828]\n *\n * Read-only by default (dryRun: true). Proposes actions but never\n * auto-posts to GitHub without explicit opt-in.\n *\n * @module dogfooding/issue-triage\n * (Source: Issue #828 — Wire remaining security modules)\n */\n\nimport type { Result } from '../core/index.js';\nimport { ok, err, createLogger, getTimeProvider } from '../core/index.js';\nimport { sanitizeInput } from '../security/input-sanitizer.js';\nimport { classifyTrust } from '../security/trust-classifier.js';\nimport type { ClassifyResult } from '../security/trust-classifier.js';\nimport { evaluatePolicy } from '../security/policy-gate.js';\nimport type { ActionContext } from '../security/policy-gate.js';\nimport { validateCorroboration } from '../security/corroboration-validator.js';\nimport type { CorroborationResult } from '../security/corroboration-validator.js';\nimport {\n assessReputation,\n ReputationCache,\n gateWithReputation,\n resolveReputationGatingMode,\n} from '../security/reputation-model.js';\nimport type {\n ReputationAssessment,\n GitHubUserMetadata,\n ReputationGateDecision,\n} from '../security/reputation-model.js';\nimport type { AgentAction, SourceCitation } from '../security/action-schema.js';\nimport { parseIssueUrl } from '../scm/url-parsers.js';\nimport { createFullGitHubProvider } from '../scm/github-provider-traits.js';\nimport type { ScmUserMetadata } from '../scm/types.js';\nimport { categorizeIssue, extractLabelsFromBody } from './issue-triage-helpers.js';\nimport type {\n IssueMetadata,\n IssueComment,\n IssueTriageConfig,\n IssueTriageResult,\n ProposedAction,\n TrustAssessment,\n} from './issue-triage-types.js';\nimport { DEFAULT_ISSUE_TRIAGE_CONFIG } from './issue-triage-types.js';\n\n// Re-export for convenience\nexport { formatTriageComment } from './issue-triage-helpers.js';\n\nconst logger = createLogger({ component: 'IssueTriage' });\n\n/**\n * GitHub issue triage processor.\n *\n * Wires all 8 security modules into a read-only triage pipeline:\n * 1. Fetch issue + comments from GitHub API\n * 2. Sanitize untrusted content (input-sanitizer)\n * 3. Classify author trust (trust-classifier)\n * 4. Assess author reputation (reputation-model) [#828]\n * 5. Generate typed actions (action-schema)\n * 6. Validate through policy gate (policy-gate)\n * 7. Validate corroboration (corroboration-validator) [#828]\n * 8. Return proposed actions\n */\nexport class IssueTriage {\n private readonly config: IssueTriageConfig;\n private readonly reputationCache: ReputationCache;\n\n constructor(config?: Partial<IssueTriageConfig>) {\n this.config = { ...DEFAULT_ISSUE_TRIAGE_CONFIG, ...config };\n this.reputationCache = new ReputationCache();\n }\n\n /**\n * Triages a GitHub issue through the full security pipeline.\n */\n async triageIssue(issueUrl: string): Promise<Result<IssueTriageResult, Error>> {\n const startTime = getTimeProvider().now();\n\n logger.info('Starting issue triage', { issueUrl });\n\n const parseResult = parseIssueUrl(issueUrl);\n if (!parseResult.ok) return parseResult;\n\n const { owner, repo, issueNumber } = parseResult.value;\n\n const fetchResult = await this.fetchIssueData(owner, repo, issueNumber);\n if (!fetchResult.ok) return fetchResult;\n\n const { issue: issueResult, comments, accountAgeDays } = fetchResult.value;\n\n // Sanitize untrusted content (Issue #828 — input-sanitizer wiring)\n const safeTitle = this.sanitizeContent(issueResult.title, issueResult.author);\n const safeBody = this.sanitizeContent(issueResult.body, issueResult.author);\n\n // Classify trust + assess reputation (Issue #828 — new wiring)\n const trustResult = this.classifyAuthor(issueResult);\n const reputation = this.assessAuthorReputation(issueResult, comments, accountAgeDays);\n\n // #3122: apply the reputation-gating rollout mode (off/audit/enforce). The\n // decision is computed once and used both to gate actions and to surface\n // observability in the result. Audit mode reports a would-be demotion\n // without enforcing it; the allowlist (Tier 1) remains the escape hatch.\n const gateDecision = gateWithReputation(\n trustResult.trustTier,\n reputation,\n resolveReputationGatingMode()\n );\n if (gateDecision.demotionSuppressed) {\n logger.warn('Reputation demotion suppressed by gating mode (would block under enforce)', {\n issueNumber,\n author: issueResult.author,\n mode: gateDecision.mode,\n classifierTier: trustResult.trustTier,\n reconciledTier: gateDecision.reconciledTier,\n });\n }\n\n // Generate and validate actions\n const actions = this.generateActions(safeTitle, safeBody, issueResult, trustResult);\n const validatedActions = this.validateActions(actions, gateDecision);\n\n const result = this.buildResult({\n issue: issueResult,\n actions: validatedActions,\n trustResult,\n reputation,\n gateDecision,\n safeContent: { title: safeTitle, body: safeBody },\n startTime,\n });\n\n logger.info('Issue triage completed', {\n issueNumber,\n category: result.category,\n actionCount: result.proposedActions.length,\n durationMs: result.totalDurationMs,\n });\n\n return ok(result);\n }\n\n /**\n * Sanitizes untrusted issue content before processing.\n * (Source: Issue #828 — input-sanitizer wiring)\n */\n private sanitizeContent(text: string, author: string): string {\n if (text.length === 0) return text;\n const result = sanitizeInput(text, 'unknown', author);\n if (result.wasModified) {\n logger.warn('Issue content sanitized', {\n author,\n strippedCount: result.strippedElements.length,\n injectionFlags: result.injectionFlags,\n });\n }\n return result.content;\n }\n\n /**\n * Classifies the issue author's trust tier.\n * (Source: Issue #828 — trust-classifier wiring)\n */\n private classifyAuthor(issue: IssueMetadata): ClassifyResult {\n return classifyTrust({\n username: issue.author,\n authorAssociation: issue.authorAssociation,\n });\n }\n\n /**\n * Assesses the issue author's reputation using the reputation model.\n * This is one of the two NEW security module wirings completing #828.\n * (Source: Issue #828 — reputation-model wiring)\n */\n private assessAuthorReputation(\n issue: IssueMetadata,\n comments: readonly IssueComment[],\n accountAgeDays: number | undefined\n ): ReputationAssessment | undefined {\n if (!this.config.enableReputation) return undefined;\n\n const sanitizeResult = sanitizeInput(issue.body, 'unknown', issue.author);\n\n // #3121: accountAgeDays is the author's REAL account age (fetched in\n // fetchIssueData) or undefined when the lookup failed. When undefined it is\n // OMITTED so the engine skips the new_account signal (#3106) — never\n // fabricated. priorContributions/recentCommentCount use real comment data.\n const metadata: GitHubUserMetadata = {\n username: issue.author,\n ...(accountAgeDays !== undefined ? { accountAgeDays } : {}),\n priorContributions: countAuthorComments(issue.author, comments),\n recentCommentCount: countRecentComments(issue.author, comments),\n recentCommentWindowMinutes: 10,\n authorAssociation: issue.authorAssociation,\n injectionFlags: sanitizeResult.injectionFlags,\n };\n\n return assessReputation(metadata, this.reputationCache);\n }\n\n /**\n * Generates typed agent actions based on issue analysis.\n */\n private generateActions(\n safeTitle: string,\n safeBody: string,\n issue: IssueMetadata,\n trustResult: ClassifyResult\n ): AgentAction[] {\n const actions: AgentAction[] = [];\n const source = this.createRepoSource(issue);\n\n // Always generate ClassifyIssue action\n const [category, confidence] = categorizeIssue(safeTitle, safeBody);\n actions.push({\n type: 'ClassifyIssue',\n category,\n confidence,\n sources: [source],\n });\n\n // Generate ProposeLabels if we found label hints\n const labels = extractLabelsFromBody(safeTitle, safeBody);\n if (labels.length > 0) {\n actions.push({\n type: 'ProposeLabels',\n labels,\n reason: `Keyword-based label extraction from issue #${String(issue.number)}`,\n sources: [source],\n });\n }\n\n // Generate SummarizeIssue for semi-trusted+ authors\n if (trustResult.trustTier === '1' || trustResult.trustTier === '2') {\n const summary = `Issue #${String(issue.number)} \"${safeTitle}\" by ${issue.author} (${trustResult.userRole})`;\n actions.push({\n type: 'SummarizeIssue',\n summary: summary.length >= 10 ? summary : `${summary} — awaiting further analysis`,\n sources: [source],\n });\n }\n\n return actions;\n }\n\n /**\n * Validates all actions through policy gate and corroboration validator.\n * This completes the #828 wiring by integrating corroboration-validator.\n * (Source: Issue #828 — policy-gate + corroboration-validator wiring)\n */\n private validateActions(\n actions: readonly AgentAction[],\n gateDecision: ReputationGateDecision\n ): ProposedAction[] {\n // #3119 + #3122: reputation GATES via the rollout mode. `enforce` uses the\n // reconciled (possibly demoted) tier; `audit`/`off` enforce the classifier\n // tier (the suppressed demotion is logged upstream). Demotion-only;\n // Tier-1/allowlist always wins.\n const context: ActionContext = {\n inputTrustTier: gateDecision.enforcedTier,\n hasWriteAccess: !this.config.dryRun,\n hasSecretAccess: false,\n };\n\n return actions.map((action) => {\n const policyDecision = evaluatePolicy(action, context);\n const corrobResult = this.validateActionCorroboration(action);\n\n return {\n type: action.type,\n description: describeAction(action),\n policyApproved: policyDecision.allowed,\n corroborated: corrobResult.satisfied,\n details: buildActionDetails(action, policyDecision, corrobResult),\n };\n });\n }\n\n /**\n * Validates corroboration for a single action.\n * This is the second NEW security module wiring completing #828.\n * (Source: Issue #828 — corroboration-validator wiring)\n */\n private validateActionCorroboration(action: AgentAction): CorroborationResult {\n return validateCorroboration(action);\n }\n\n /**\n * Builds the final triage result.\n */\n private buildResult(opts: {\n issue: IssueMetadata;\n actions: readonly ProposedAction[];\n trustResult: ClassifyResult;\n reputation: ReputationAssessment | undefined;\n gateDecision: ReputationGateDecision;\n safeContent: { title: string; body: string };\n startTime: number;\n }): IssueTriageResult {\n const { issue, actions, trustResult, reputation, gateDecision, safeContent, startTime } = opts;\n const [category, confidence] = categorizeIssue(safeContent.title, safeContent.body);\n\n // Tier 1 actors (owner/maintainer) cannot be suspicious — reconcile\n // the trust-classifier result with the reputation-model result.\n const isTier1 = trustResult.trustTier === '1';\n\n const trustAssessment: TrustAssessment = {\n trustTier: trustResult.trustTier,\n userRole: trustResult.userRole,\n isAllowlisted: trustResult.isAllowlisted,\n reputationScore: reputation?.reputationScore,\n suspiciousSignals: isTier1 ? [] : (reputation?.suspiciousSignals ?? []),\n isSuspicious: isTier1 ? false : (reputation?.isSuspicious ?? false),\n // #3122: surface both the enforced tier (what the gate used) and the\n // reconciled tier (what reputation computed) so telemetry can't mistake\n // a would-be demotion for an enforced one.\n enforcedTrustTier: gateDecision.enforcedTier,\n reputationReconciledTier: gateDecision.reconciledTier,\n gatingMode: gateDecision.mode,\n };\n\n return {\n issueNumber: issue.number,\n repository: `${issue.owner}/${issue.repo}`,\n proposedActions: actions,\n trustAssessment,\n category,\n categoryConfidence: confidence,\n totalDurationMs: getTimeProvider().now() - startTime,\n timestamp: getTimeProvider().nowIso(),\n };\n }\n\n /**\n * Creates a repo file source citation for the triage.\n */\n private createRepoSource(issue: IssueMetadata): SourceCitation {\n return {\n type: 'repoFile',\n path: `issues/${String(issue.number)}`,\n };\n }\n\n /**\n * Fetches issue data from the SCM provider and maps to dogfooding types.\n */\n private async fetchIssueData(\n owner: string,\n repo: string,\n issueNumber: number\n ): Promise<\n Result<{ issue: IssueMetadata; comments: IssueComment[]; accountAgeDays?: number }, Error>\n > {\n const provider = createFullGitHubProvider(`${owner}/${repo}`);\n\n const detailResult = await provider.getIssueDetail(issueNumber);\n if (!detailResult.ok) return err(detailResult.error);\n\n const detail = detailResult.value;\n const issue: IssueMetadata = {\n number: detail.number,\n title: detail.title,\n body: detail.body,\n author: detail.author,\n authorAssociation: detail.authorAssociation,\n owner,\n repo,\n url: detail.url,\n state: detail.state,\n labels: [...detail.labels],\n createdAt: detail.createdAt,\n };\n\n const commentsResult = await provider.listCommentDetails(issueNumber);\n const comments: IssueComment[] = commentsResult.ok\n ? commentsResult.value.map((c) => ({\n id: c.id,\n body: c.body,\n author: c.author,\n authorAssociation: c.authorAssociation,\n createdAt: c.createdAt,\n }))\n : [];\n\n // #3121: fetch the author's REAL account age (their account creation date,\n // not the issue date). Best-effort — on failure or an unparseable date we\n // omit it, so the reputation engine SKIPS the new_account signal (#3106)\n // rather than fabricating a value. Reputation must not block on this.\n const accountAgeDays = await this.fetchAccountAgeDays(provider, detail.author);\n\n return ok(\n accountAgeDays !== undefined ? { issue, comments, accountAgeDays } : { issue, comments }\n );\n }\n\n /**\n * Best-effort lookup of a GitHub user's account age in days. Returns\n * `undefined` if the user-metadata fetch fails or the creation date can't be\n * parsed (#3121) — callers must treat absence as \"unknown\", not \"benign\".\n */\n private async fetchAccountAgeDays(\n provider: { fetchUserMetadata: (u: string) => Promise<Result<ScmUserMetadata, Error>> },\n username: string\n ): Promise<number | undefined> {\n try {\n const result = await provider.fetchUserMetadata(username);\n if (!result.ok) return undefined;\n const createdMs = Date.parse(result.value.createdAt);\n if (!Number.isFinite(createdMs)) return undefined;\n return Math.floor((getTimeProvider().now() - createdMs) / 86_400_000);\n } catch {\n // Truly best-effort: even an unexpected rejection (token resolution,\n // transport) must not break triage — fall back to \"unknown\" age.\n return undefined;\n }\n }\n}\n\n// ============================================================================\n// Private Helpers\n// ============================================================================\n\n/** Counts how many comments the author has made on the issue. */\nfunction countAuthorComments(author: string, comments: readonly IssueComment[]): number {\n return comments.filter((c) => c.author === author).length;\n}\n\n/** Counts recent comments from the author (within 10 minutes). */\nfunction countRecentComments(author: string, comments: readonly IssueComment[]): number {\n const tenMinutesAgo = Date.now() - 10 * 60 * 1000;\n return comments.filter(\n (c) => c.author === author && new Date(c.createdAt).getTime() > tenMinutesAgo\n ).length;\n}\n\n/** Creates a human-readable description for a typed action. */\nfunction describeAction(action: AgentAction): string {\n switch (action.type) {\n case 'ClassifyIssue':\n return `Classified as ${action.category} (${String(Math.round(action.confidence * 100))}% confidence)`;\n case 'ProposeLabels':\n return `Suggest labels: ${action.labels.join(', ')}`;\n case 'SummarizeIssue':\n return action.summary.slice(0, 100);\n default:\n return `${action.type} action`;\n }\n}\n\n/** Builds details object for a proposed action. */\nfunction buildActionDetails(\n action: AgentAction,\n policy: { allowed: boolean; violations: readonly { rule: string; message: string }[] },\n corrob: CorroborationResult\n): Record<string, unknown> {\n return {\n policyViolations: policy.violations.map((v) => v.rule),\n missingCorroboration: corrob.missing,\n ...(action.type === 'ClassifyIssue' && { category: action.category }),\n ...(action.type === 'ProposeLabels' && { labels: action.labels }),\n };\n}\n\n/**\n * Creates an IssueTriage instance.\n */\nexport function createIssueTriage(config?: Partial<IssueTriageConfig>): IssueTriage {\n return new IssueTriage(config);\n}\n"],"mappings":"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","names":["z","z","z","logger"]}
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
getErrorMessage,
|
|
5
5
|
getTimeProvider,
|
|
6
6
|
ok
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-VY5WEC2D.js";
|
|
8
8
|
|
|
9
9
|
// src/context/session-memory.ts
|
|
10
10
|
import * as fs from "fs";
|
|
@@ -351,4 +351,4 @@ export {
|
|
|
351
351
|
SessionMemory,
|
|
352
352
|
createSessionMemory
|
|
353
353
|
};
|
|
354
|
-
//# sourceMappingURL=chunk-
|
|
354
|
+
//# sourceMappingURL=chunk-FDY6YOFG.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getErrorMessage
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-VY5WEC2D.js";
|
|
4
4
|
|
|
5
5
|
// src/cli/setup-config.ts
|
|
6
6
|
import { copyFileSync, existsSync, mkdirSync, writeFileSync } from "fs";
|
|
@@ -77,4 +77,4 @@ function ensureBackup(outputPath) {
|
|
|
77
77
|
export {
|
|
78
78
|
runConfigInitSync
|
|
79
79
|
};
|
|
80
|
-
//# sourceMappingURL=chunk-
|
|
80
|
+
//# sourceMappingURL=chunk-FFJEERPZ.js.map
|
|
@@ -4,24 +4,24 @@ import {
|
|
|
4
4
|
PROVIDER_ENV_KEYS,
|
|
5
5
|
assertCustomApiHostResolvesPublic,
|
|
6
6
|
validateCustomApiBaseUrl
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-4A6MSCNJ.js";
|
|
8
8
|
import {
|
|
9
9
|
AdapterModelError,
|
|
10
10
|
BaseAdapter,
|
|
11
11
|
createStream,
|
|
12
12
|
requireApiKey,
|
|
13
13
|
validateApiKeyPresence
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-A4MPCXZ7.js";
|
|
15
15
|
import {
|
|
16
16
|
CliCircuitBreaker,
|
|
17
17
|
DEFAULT_CIRCUIT_BREAKER_CONFIG
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-ADIJIYFA.js";
|
|
19
19
|
import {
|
|
20
20
|
getAvailabilityCache
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-2Z4V5THE.js";
|
|
22
22
|
import {
|
|
23
23
|
generateHyphenId
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-E4LAXVQE.js";
|
|
25
25
|
import {
|
|
26
26
|
CLI_SUBPROCESS_TIMEOUTS,
|
|
27
27
|
CLI_TIMEOUTS,
|
|
@@ -57,7 +57,7 @@ import {
|
|
|
57
57
|
loadModelsDevSnapshot,
|
|
58
58
|
ok,
|
|
59
59
|
resolveCliAlias
|
|
60
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-VY5WEC2D.js";
|
|
61
61
|
|
|
62
62
|
// src/cli-adapters/cli-to-model-adapter.ts
|
|
63
63
|
var CliToModelAdapter = class {
|
|
@@ -4838,4 +4838,4 @@ export {
|
|
|
4838
4838
|
SdkAdapter,
|
|
4839
4839
|
createAutoAdapter
|
|
4840
4840
|
};
|
|
4841
|
-
//# sourceMappingURL=chunk-
|
|
4841
|
+
//# sourceMappingURL=chunk-IZO437XR.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runConfigInitSync
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-FFJEERPZ.js";
|
|
4
4
|
import {
|
|
5
5
|
VERSION,
|
|
6
6
|
checkApiKeys,
|
|
@@ -8,13 +8,13 @@ import {
|
|
|
8
8
|
checkSqlite,
|
|
9
9
|
defaultConfig,
|
|
10
10
|
initDataDirectories
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-3XLDANPJ.js";
|
|
12
12
|
import {
|
|
13
13
|
BUILT_IN_EXPERTS
|
|
14
14
|
} from "./chunk-ZM4O442V.js";
|
|
15
15
|
import {
|
|
16
16
|
probeAllClis
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-IZO437XR.js";
|
|
18
18
|
import {
|
|
19
19
|
CLI_SUBPROCESS_TIMEOUTS,
|
|
20
20
|
colors,
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
getErrorMessage,
|
|
26
26
|
getTimeProvider,
|
|
27
27
|
symbols
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-VY5WEC2D.js";
|
|
29
29
|
import {
|
|
30
30
|
ensureGitignored,
|
|
31
31
|
findRepoRoot
|
|
@@ -2000,4 +2000,4 @@ export {
|
|
|
2000
2000
|
setupCommand,
|
|
2001
2001
|
setupCommandAsync
|
|
2002
2002
|
};
|
|
2003
|
-
//# sourceMappingURL=chunk-
|
|
2003
|
+
//# sourceMappingURL=chunk-KY2QMH3C.js.map
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
GitHubProvider,
|
|
3
3
|
ScmError
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ULIAUMQD.js";
|
|
5
5
|
import {
|
|
6
6
|
resolveToken
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-YHBVFTRG.js";
|
|
8
8
|
import {
|
|
9
9
|
err,
|
|
10
10
|
ok
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-VY5WEC2D.js";
|
|
12
12
|
|
|
13
13
|
// src/scm/factory.ts
|
|
14
14
|
async function createScmProvider(config) {
|
|
@@ -41,4 +41,4 @@ export {
|
|
|
41
41
|
createScmProvider,
|
|
42
42
|
createGitHubProvider
|
|
43
43
|
};
|
|
44
|
-
//# sourceMappingURL=chunk-
|
|
44
|
+
//# sourceMappingURL=chunk-OGOE3NW5.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SessionMemory
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-FDY6YOFG.js";
|
|
4
4
|
import {
|
|
5
5
|
stringifyValue,
|
|
6
6
|
tokenize,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from "./chunk-PQHVC4BD.js";
|
|
12
12
|
import {
|
|
13
13
|
generateId
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-E4LAXVQE.js";
|
|
15
15
|
import {
|
|
16
16
|
ErrorCode,
|
|
17
17
|
NexusError,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
getTimeProvider,
|
|
25
25
|
ok,
|
|
26
26
|
setSharedMobiMemDbPathResolver
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-VY5WEC2D.js";
|
|
28
28
|
import {
|
|
29
29
|
nexusDataPath
|
|
30
30
|
} from "./chunk-ZGLIHPGJ.js";
|
|
@@ -5612,4 +5612,4 @@ export {
|
|
|
5612
5612
|
reinitializeMemoryBackends,
|
|
5613
5613
|
ToolMemoryManager
|
|
5614
5614
|
};
|
|
5615
|
-
//# sourceMappingURL=chunk-
|
|
5615
|
+
//# sourceMappingURL=chunk-PM4MZHQK.js.map
|