# jyz922/joke_identification architecture

> Architecture diagram of the GitHub repository jyz922/joke_identification, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/jyz922/joke_identification
- Repository: https://github.com/jyz922/joke_identification

## Overview

DoubleTake is an age-aware detector of humor built on homographic ambiguity and compound splits. A request enters the runner, passes through scope, surface, sense retrieval, candidate ranking, anchoring, form-specific resolution, distinctness, comprehension, and appropriateness checks, then produces a structured verdict. The README documents genre-specific resolution and two-axis age assessment. Sampled source confirms runner orchestration, lexical resources, and provider use; some individual layer wiring is inferred from the documented pipeline and layer registry, so uncertain links are omitted.

Main entry points: [`src/doubletake/layers.py`](https://github.com/jyz922/joke_identification/blob/main/src/doubletake/layers.py) (Layer registry), [`src/doubletake/runner.py`](https://github.com/jyz922/joke_identification/blob/main/src/doubletake/runner.py) (Pipeline runner), [`src/doubletake/providers.py`](https://github.com/jyz922/joke_identification/blob/main/src/doubletake/providers.py) (Provider abstraction), [`src/doubletake/l2_senses.py`](https://github.com/jyz922/joke_identification/blob/main/src/doubletake/l2_senses.py) (Sense retrieval)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_pipeline["Wordplay analysis"]
  node_l0["Scope declaration<br/>[l0_scope.py]"]
  node_l1["Surface and genre<br/>[l1_surface.py]"]
  node_l2["Sense retrieval<br/>[l2_senses.py]"]
  node_l3["Candidate ranking<br/>[l3_candidates.py]"]
  node_l4["Sense anchoring<br/>[l4_anchoring.py]"]
  node_l5["Semantic resolution<br/>[l5_resolution.py]"]
  node_l6["Sense distinctness<br/>[l6_distinctness.py]"]
  node_layers["Layer registry<br/>[layers.py]"]
end

subgraph group_age["Age evaluation"]
  node_l7["Comprehension"]
  node_l8["Appropriateness"]
end

subgraph group_integration["Model integration"]
  node_providers["Provider abstraction<br/>[providers.py]"]
end

subgraph group_records["Request and results"]
  node_runner["Pipeline runner<br/>[runner.py]"]
  node_settings["Settings<br/>[config.py]"]
  node_schema["Analysis schema<br/>[schema.py]"]
  node_result["Structured verdict"]
end

node_user(("Text and age"))
node_lexical[("Lexical resources")]
node_llm{{"LLM providers"}}

node_user -->|"submits"| node_runner
node_runner -->|"preprocesses"| node_l0
node_runner -->|"dispatches"| node_layers
node_layers -->|"runs"| node_l1
node_layers -->|"runs"| node_l2
node_layers -->|"runs"| node_l3
node_layers -->|"runs"| node_l4
node_layers -->|"runs"| node_l5
node_layers -->|"runs"| node_l6
node_layers -->|"runs"| node_l7
node_layers -->|"runs"| node_l8
node_l2 -->|"retrieves from"| node_lexical
node_l4 -->|"calls"| node_providers
node_l5 -->|"calls"| node_providers
node_l6 -->|"calls"| node_providers
node_l7 -->|"calls"| node_providers
node_l8 -->|"calls"| node_providers
node_providers -->|"calls"| node_llm
node_runner -->|"uses"| node_settings
node_runner -->|"builds records"| node_schema
node_runner -->|"renders"| node_result

click node_runner "https://github.com/jyz922/joke_identification/blob/main/src/doubletake/runner.py"
click node_l0 "https://github.com/jyz922/joke_identification/blob/main/src/doubletake/l0_scope.py"
click node_l1 "https://github.com/jyz922/joke_identification/blob/main/src/doubletake/l1_surface.py"
click node_l2 "https://github.com/jyz922/joke_identification/blob/main/src/doubletake/l2_senses.py"
click node_l3 "https://github.com/jyz922/joke_identification/blob/main/src/doubletake/l3_candidates.py"
click node_l4 "https://github.com/jyz922/joke_identification/blob/main/src/doubletake/l4_anchoring.py"
click node_l5 "https://github.com/jyz922/joke_identification/blob/main/src/doubletake/l5_resolution.py"
click node_l6 "https://github.com/jyz922/joke_identification/blob/main/src/doubletake/l6_distinctness.py"
click node_l7 "https://github.com/jyz922/joke_identification/blob/main/src/doubletake/l7_comprehension.py"
click node_l8 "https://github.com/jyz922/joke_identification/blob/main/src/doubletake/l8_appropriateness.py"
click node_layers "https://github.com/jyz922/joke_identification/blob/main/src/doubletake/layers.py"
click node_providers "https://github.com/jyz922/joke_identification/blob/main/src/doubletake/providers.py"
click node_settings "https://github.com/jyz922/joke_identification/blob/main/src/doubletake/config.py"
click node_schema "https://github.com/jyz922/joke_identification/blob/main/src/doubletake/schema.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_l0,node_l1,node_l2,node_l3,node_l4,node_l5,node_l6,node_layers toneBlue
class node_l7,node_l8,node_lexical toneAmber
class node_providers toneMint
class node_runner,node_settings,node_schema,node_result toneRose
class node_user,node_llm toneIndigo
```

## Components

### Wordplay analysis

- [Scope declaration](https://github.com/jyz922/joke_identification/blob/main/src/doubletake/l0_scope.py): `src/doubletake/l0_scope.py`
- [Surface and genre](https://github.com/jyz922/joke_identification/blob/main/src/doubletake/l1_surface.py): `src/doubletake/l1_surface.py`
- [Sense retrieval](https://github.com/jyz922/joke_identification/blob/main/src/doubletake/l2_senses.py): `src/doubletake/l2_senses.py`
- [Candidate ranking](https://github.com/jyz922/joke_identification/blob/main/src/doubletake/l3_candidates.py): `src/doubletake/l3_candidates.py`
- [Sense anchoring](https://github.com/jyz922/joke_identification/blob/main/src/doubletake/l4_anchoring.py): `src/doubletake/l4_anchoring.py`
- [Semantic resolution](https://github.com/jyz922/joke_identification/blob/main/src/doubletake/l5_resolution.py): `src/doubletake/l5_resolution.py`
- [Sense distinctness](https://github.com/jyz922/joke_identification/blob/main/src/doubletake/l6_distinctness.py): `src/doubletake/l6_distinctness.py`
- [Layer registry](https://github.com/jyz922/joke_identification/blob/main/src/doubletake/layers.py): `src/doubletake/layers.py`

### Age evaluation

- [Comprehension](https://github.com/jyz922/joke_identification/blob/main/src/doubletake/l7_comprehension.py): `src/doubletake/l7_comprehension.py`
- [Appropriateness](https://github.com/jyz922/joke_identification/blob/main/src/doubletake/l8_appropriateness.py): `src/doubletake/l8_appropriateness.py`

### Model integration

- [Provider abstraction](https://github.com/jyz922/joke_identification/blob/main/src/doubletake/providers.py): `src/doubletake/providers.py`

### Request and results

- [Pipeline runner](https://github.com/jyz922/joke_identification/blob/main/src/doubletake/runner.py): `src/doubletake/runner.py`
- [Settings](https://github.com/jyz922/joke_identification/blob/main/src/doubletake/config.py): `src/doubletake/config.py`
- [Analysis schema](https://github.com/jyz922/joke_identification/blob/main/src/doubletake/schema.py): `src/doubletake/schema.py`
- **Structured verdict**

### Other components

- **Text and age**
- **Lexical resources**
- **LLM providers**

## Connections

- Text and age → Pipeline runner: submits
- Pipeline runner → Scope declaration: preprocesses
- Pipeline runner → Layer registry: dispatches
- Layer registry → Surface and genre: runs
- Layer registry → Sense retrieval: runs
- Layer registry → Candidate ranking: runs
- Layer registry → Sense anchoring: runs
- Layer registry → Semantic resolution: runs
- Layer registry → Sense distinctness: runs
- Layer registry → Comprehension: runs
- Layer registry → Appropriateness: runs
- Sense retrieval → Lexical resources: retrieves from
- Sense anchoring → Provider abstraction: calls
- Semantic resolution → Provider abstraction: calls
- Sense distinctness → Provider abstraction: calls
- Comprehension → Provider abstraction: calls
- Appropriateness → Provider abstraction: calls
- Provider abstraction → LLM providers: calls
- Pipeline runner → Settings: uses
- Pipeline runner → Analysis schema: builds records
- Pipeline runner → Structured verdict: renders
