@@ -49,10 +49,18 @@ const VALID_RISK_LEVELS: &[&str] = &["low", "medium", "high", "critical"];
4949/// Valid confidence levels
5050const VALID_CONFIDENCES : & [ & str ] = & [ "low" , "medium" , "high" ] ;
5151
52- /// Patterns that indicate sensitive information
52+ /// Patterns that indicate sensitive information.
53+ /// These are checked against the document body. Patterns should be specific enough
54+ /// to avoid false positives in documentation that describes auth flows.
5355const SENSITIVE_PATTERNS : & [ & str ] = & [
54- "password:" , "api_key:" , "secret:" , "token:" , "private_key:" ,
55- "credentials:" , "Bearer " , "AWS_SECRET" , "PRIVATE KEY" ,
56+ "password:" , "api_key:" , "secret:" , "private_key:" ,
57+ "credentials:" , "AWS_SECRET" , "PRIVATE KEY" ,
58+ ] ;
59+
60+ /// Patterns that are suspicious but common in documentation describing auth flows.
61+ /// These produce warnings instead of errors.
62+ const SOFT_SENSITIVE_PATTERNS : & [ & str ] = & [
63+ "token:" , "Bearer " ,
5664] ;
5765
5866/// Validate all documents found under a .devtrail/ directory
@@ -489,12 +497,20 @@ fn check_type_specific(result: &mut ValidationResult, doc: &DevTrailDocument) {
489497}
490498
491499/// REF-001: Check that documents listed in related: exist
500+ /// Only validates references that look like DevTrail document IDs (e.g., AILOG-2025-01-27-001).
501+ /// Skips task IDs (T025), requirement IDs (FR-019, US2), risk IDs (RISK-001),
502+ /// external paths, and other non-document references to avoid false positives.
492503fn check_related_exist ( result : & mut ValidationResult , doc : & DevTrailDocument , devtrail_dir : & Path ) {
493504 if let Some ( related) = & doc. frontmatter . related {
494505 for rel_id in related {
495506 if rel_id. is_empty ( ) {
496507 continue ;
497508 }
509+ // Only validate references that look like DevTrail document IDs
510+ // (start with a known document type prefix followed by a dash)
511+ if !looks_like_devtrail_id ( rel_id) {
512+ continue ;
513+ }
498514 // Search for a file matching this id
499515 if !find_document_by_id ( devtrail_dir, rel_id) {
500516 result. add ( ValidationIssue {
@@ -509,6 +525,15 @@ fn check_related_exist(result: &mut ValidationResult, doc: &DevTrailDocument, de
509525 }
510526}
511527
528+ /// Check if a reference looks like a DevTrail document ID.
529+ /// Matches patterns like "AILOG-2025-01-27-001" or "ADR-2025-01-27-001-title".
530+ /// Returns false for task IDs (T025), requirement IDs (FR-019, US2), paths, etc.
531+ fn looks_like_devtrail_id ( id : & str ) -> bool {
532+ DocType :: ALL_PREFIXES . iter ( ) . any ( |prefix| {
533+ id. starts_with ( prefix) && id. get ( prefix. len ( ) ..prefix. len ( ) + 1 ) == Some ( "-" )
534+ } )
535+ }
536+
512537/// META-004: Check that filename date matches created field
513538fn check_date_consistency ( result : & mut ValidationResult , doc : & DevTrailDocument ) {
514539 let Some ( created) = & doc. frontmatter . created else {
@@ -570,6 +595,18 @@ fn check_sensitive_info(result: &mut ValidationResult, doc: &DevTrailDocument) {
570595 } ) ;
571596 }
572597 }
598+ // Soft patterns: common in auth documentation, warn instead of error
599+ for pattern in SOFT_SENSITIVE_PATTERNS {
600+ if full_content. contains ( pattern) {
601+ result. add ( ValidationIssue {
602+ file : doc. path . clone ( ) ,
603+ rule : "SEC-001" . to_string ( ) ,
604+ message : format ! ( "Review for sensitive information: '{}' (may be documentation context)" , pattern. trim( ) ) ,
605+ severity : Severity :: Warning ,
606+ fix_hint : Some ( "Verify this is documentation context, not an actual secret" . to_string ( ) ) ,
607+ } ) ;
608+ }
609+ }
573610}
574611
575612/// OBS-001: If document has tag 'observabilidad' or 'observability', check for relevant sections
0 commit comments