Skip to content

Work Classifier

The work classifier determines the domain of a Work Unit using weighted signals from code paths, lane names, WU type, and description keywords. It returns abstract capability tags and test methodology hints for vendor-agnostic integration.

Classify the work domain from multiple weighted signals.

Parameters:

ParameterTypeDescription
docobjectWU document with code_paths, lane, type, description
configWorkClassificationConfigOptional config to extend default patterns

Returns: WorkClassification

import { classifyWork, WORK_DOMAINS } from '@lumenflow/core';

const result = classifyWork({
  code_paths: ['src/components/Button.tsx'],
  lane: 'Framework: Core',
});
// { domain: 'ui', confidence: 1.0, signals: [...], capabilities: [...], testMethodologyHint: 'smoke-test' }
interface WorkClassification {
  /** Detected work domain: 'ui' | 'backend' | 'docs' | 'infra' | 'mixed' */
  domain: WorkDomain;
  /** Confidence score (max signal weight, 0 if no match) */
  confidence: number;
  /** Individual signals that contributed to classification */
  signals: WorkSignal[];
  /** Abstract capability tags (NOT client skill names) */
  capabilities: string[];
  /** Test methodology hint, e.g. 'smoke-test' for UI work */
  testMethodologyHint?: string;
}
interface WorkSignal {
  source: string; // 'code_paths' | 'lane' | 'type' | 'description'
  domain: WorkDomain;
  weight: number;
  match: string; // The pattern or keyword that matched
}
SignalWeightDescription
code_paths1.0Glob pattern matching against file paths
lane0.6Lane parent/sublane name matching
type0.3WU type field (e.g., documentation)
description0.2Keyword matching in description text

Confidence = max(matched signal weights), not sum. Domain is assigned only when confidence >= 0.3.

const WORK_DOMAINS = {
  UI: 'ui',
  BACKEND: 'backend',
  DOCS: 'docs',
  INFRA: 'infra',
  MIXED: 'mixed',
};
const SIGNAL_WEIGHTS = {
  CODE_PATHS: 1.0,
  LANE: 0.6,
  TYPE: 0.3,
  DESCRIPTION: 0.2,
};

Built-in glob patterns for detecting UI work via code paths:

  • **/*.css, **/*.scss, **/*.less
  • **/*.module.css, **/*.module.scss
  • **/*.styled.ts, **/*.styled.tsx
  • **/components/**, **/pages/**
  • **/app/**/page.tsx, **/app/**/layout.tsx (and variants)

Built-in lane parent hints: Experience, Frontend, UI, Design.

The classifier returns abstract capability tags (not client-specific skill names):

DomainCapabilities
uiui-design-awareness, component-reuse-check
docsdocumentation-structure, link-validation
infrainfrastructure-review, security-check
mixedcross-domain-awareness
backend(none)

Extend default patterns via methodology.work_classification in workspace.yaml. Custom values extend the built-in defaults; they do not replace them.

methodology:
  work_classification:
    ui:
      code_path_patterns:
        - 'src/widgets/*.tsx'
        - 'src/views/**'
      lane_hints:
        - 'Design'
        - 'Visual'
interface WorkClassificationConfig {
  ui?: {
    /** Additional glob patterns (extend defaults) */
    code_path_patterns?: string[];
    /** Additional lane hints (extend defaults) */
    lane_hints?: string[];
  };
}

When the detected domain is ui and confidence >= 0.5, the classifier returns testMethodologyHint: 'smoke-test'. This signals to consumers (like wu:brief) that visual smoke tests should be recommended alongside unit tests.

The work classifier is wired into wu:brief generation (WU-1900) at three points:

Capabilities are mapped to client-specific skills via capabilities_map in client config:

agents:
  clients:
    claude-code:
      capabilities_map:
        ui-design-awareness: frontend-design
        component-reuse-check: library-first

When classifier capabilities match keys in the map, the corresponding skill names appear in the brief’s Soft Policy section. This keeps the classifier vendor-agnostic while allowing each client to define its own skill names.

A ## Design Context section is added to the brief for UI-classified work, with guidance on pattern checks, viewport verification, and accessibility. This section contains no /skill syntax or client-specific names.

The constraints block’s TDD CHECKPOINT is omitted when work is classified as UI domain or methodology is none.

classifyWork({
  code_paths: ['apps/web/src/styles/main.css'],
  lane: 'Framework: Core',
});
// domain: 'ui', confidence: 1.0
classifyWork({
  type: 'documentation',
  code_paths: [],
});
// domain: 'docs', confidence: 0.3
classifyWork({
  code_paths: ['src/components/Header.tsx', 'docs/api.md'],
});
// domain: 'mixed', confidence: 1.0
classifyWork({
  code_paths: ['packages/core/src/utils.ts'],
});
// domain: 'backend', confidence: 0