## Signals


## Clause


One dependency-aware pattern matched against each sentence of a text.


Usage

``` python
Clause(
    *, noun=None, verb=None, adj=None, negated=False, tense="any", subject=()
)
```


Anchors on `noun` when set (a NOUN/PROPN lemma hit), else on `verb` (a VERB/AUX lemma hit); every other constraint must hold on a token dependency-related to the anchor.


#### Attributes


`noun: `<a href="signals.html#captain_hook.Phrase" class="gdls-link gdls-code"><code>Phrase</code></a>` | None`  
Noun phrase the clause anchors on, when set.

`verb: `<a href="signals.html#captain_hook.Phrase" class="gdls-link gdls-code"><code>Phrase</code></a>` | None`  
Verb phrase; the anchor when `noun` is unset, otherwise a constraint dependency-related to the noun anchor.

`adj: `<a href="signals.html#captain_hook.Phrase" class="gdls-link gdls-code"><code>Phrase</code></a>` | None`  
Adjective/adverb phrase (pos ADJ/ADV/PART) related to the anchor.

`negated: bool`  
Require a negation (`neg` dependency) related to the anchor.

`tense: Literal[``"any", `<span class="st">`"completed"``, ``"prospective"``]`</span>  
Constrain the verb's tense (see [is_past_predicate](signals.md#captain_hook.is_past_predicate)). `"any"` (default) applies no constraint; `"completed"` matches only verbs reported as done -- "removed the retry logic" but not "remove the node" or "will be removed later"; `"prospective"` matches only verbs that are *not* past predicates and *not* counterfactual modal-perfects -- "will leave"/"leaving"/"leave it"/"will have left" but not "left the workspace", "left to clean up", or "should have left".

`subject: SubjectKind | tuple[SubjectKind, …]`  
The subject shapes the verb may have (see [subject_kind](signals.md#captain_hook.subject_kind)), as a tuple -- `()` (default) applies no constraint, and a bare string means that one shape. `"unnamed"`: no substantive active subject -- imperatives ("switch back to plan mode"), pronoun subjects ("we should replan"), and true passives ("the file was removed"). `"passive"`: a substantive subject but no direct object -- elliptical passives ("config moved to settings.py") and intransitive actives ("the parser crashed"). `"actor"`: a substantive subject acting on a direct object -- described behavior like "the parser removed the node". `("unnamed",)` matches directives but not descriptions; `("unnamed", "passive")` also admits statements about the thing acted on.


#### Example

``` python
>>> Clause(verb=Phrase("remove", "delete"), tense="completed", subject=("unnamed", "passive"))
```


## NlpSignal


A transcript signal that scores `weight` when any clause matches a sentence.


Usage

``` python
NlpSignal(*, clauses, weight=1)
```


#### Parameter Attributes


`clauses: Sequence[`<a href="signals.html#captain_hook.Clause" class="gdls-link gdls-code"><code>Clause</code></a>`]`  

`weight: int = ``1`  


#### Example

``` python
>>> NlpSignal(clauses=[Clause(noun=Phrase("quota"), verb=Phrase("exceed"))], weight=2)
```


## Phrase


A set of lowercased lemmas naming one concept, matched against tokens by lemma.


Usage

``` python
Phrase(*terms)
```


Multi-word terms ("rate limit") match a head token whose `compound` children supply the remaining words.


#### Example

``` python
>>> Phrase("remove", "delete", "drop")
```


#### Methods

| Name | Description |
|----|----|
| [expand()](#captain_hook.Phrase.expand) | Phrase covering `terms` plus their WordNet synonyms for `pos`. |


##### expand()


Phrase covering `terms` plus their WordNet synonyms for `pos`.


Usage

``` python
expand(*terms, pos="n")
```


The WordNet expansion is deferred to the first predicate use of the returned phrase (its `~ExpandedPhrase.lemmas` are computed once, on first read), so building a signal -- and importing the pack that builds it -- never loads the lexicon.


##### Example

``` python
>>> Phrase.expand("issue")  # issue, consequence, effect, outcome, ...
```


## is_past_predicate()


Whether `tok` reports a completed action.


Usage

``` python
is_past_predicate(tok)
```


True for a past-tense or participial predicate (tag `VBD`/`VBN`) used predicatively (`dep_` is not `amod`) with no present-tense or modal auxiliary child, exempting perfect "have" -- so "removed the retry logic", "was moved to utils.py", and "has been removed" qualify while "removes stale entries", "is removed when it expires", and "will be moved later" do not.


## has_nominal_subject()


Whether `tok` has a substantive active subject.


Usage

``` python
has_nominal_subject(tok)
```


True when `tok` has a letter-bearing, non-pronoun `nsubj` child -- "the parser removed the node" has one, while pronoun subjects ("we removed it") and passive subjects (`nsubjpass`) do not count.


## subject_kind()


The shape of `tok`'s subject, as [Clause](signals.md#captain_hook.Clause)'s `subject` constraint sees it.


Usage

``` python
subject_kind(tok)
```


`"unnamed"` -- no substantive active subject (see [has_nominal_subject](signals.md#captain_hook.has_nominal_subject)); `"actor"` -- a substantive subject plus a direct object; `"passive"` -- a substantive subject without one.
