hired.candidate.knowledge_base#

The candidate knowledge base: a facade over the user-level store.

CandidateKnowledgeBase is the domain-driven entry point for accumulating and querying knowledge about one candidate — what is true about them, reusable across every job application. It wraps the UserStore with validated, intention-revealing methods (add_fact, facts, record_qa, save_upload, …) and keeps a regenerated, human-readable synopsis() projection of the fact store for fast context loading.

Work tied to a specific company’s role(s) — alignment reports, company research, interview prep — does not live here; it lives in a per-engagement JDWorkspace, reached via jd().

Classes

CandidateKnowledgeBase([user, store])

Accumulated, open-world knowledge about a single candidate (user-level).

class hired.candidate.knowledge_base.CandidateKnowledgeBase(user='me', *, store=None)[source]#

Bases: object

Accumulated, open-world knowledge about a single candidate (user-level).

>>> import tempfile, os
>>> os.environ['HIRED_DATA_DIR'] = tempfile.mkdtemp()
>>> kb = CandidateKnowledgeBase()                 # default candidate "me"
>>> from hired.candidate.base import Fact, FactCategory
>>> _ = kb.add_fact(Fact(statement='Built ML pipelines in Python',
...                       category=FactCategory.SKILL, tags=['python', 'ml']))
>>> [f.statement for f in kb.facts(category=FactCategory.SKILL)]
['Built ML pipelines in Python']
>>> [f.statement for f in kb.facts(tags=['ml'])]
['Built ML pipelines in Python']
add_fact(fact)[source]#

Persist a fact, returning its id.

Return type:

str

add_note(subject, text=None, *, files=None)[source]#

Record volunteered info about a subject into its dossier.

text is appended to the dossier’s overview.md; files (a {name: bytes} mapping) are attached as detail/media. Returns the dossier. This is the “by the way, I also did X” entry point — a single sentence or a whole folder both land here.

Return type:

TopicDossier

add_source(src, *, name=None)[source]#

Store a raw source (file path or bytes) and record its content digest.

Returns the source key (its name in the raw store). The digest (in state.json) lets a later refresh detect new/changed sources without re-reading everything. Facts extracted from a source cite it by this key.

Return type:

str

facts(*, category=None, tags=None, status=FactStatus.ASSERTED, include_negations=True)[source]#

Iterate facts, optionally filtered by category/tags/status.

By default only ASSERTED facts are returned (superseded ones are hidden). tags matches facts containing any of the given tags.

Return type:

Iterator[Fact]

jd(jd_id, *, company=None, label=None)[source]#

Get-or-create the workspace for an engagement (1+ JDs of one company).

company / label are recorded in the engagement’s meta when given.

Return type:

JDWorkspace

jds()[source]#

Ids of all engagements for this candidate.

Return type:

list[str]

needs_refresh()[source]#

True when uningested source/Q&A material exists (refresh warranted).

Return type:

bool

pending_qa()[source]#

Q&A entries not yet distilled into facts.

Return type:

list[QAEntry]

pending_sources()[source]#

Raw sources new, changed, or not yet distilled into facts.

Return type:

list[str]

record_qa(entry, *, derived_facts=None)[source]#

Append a clarifying Q&A exchange; optionally distill it into facts.

When derived_facts (atomic fact records extracted from the answer) are given, they are ingested with SourceKind.QA provenance (source_id = the Q&A id, quotes verified against the answer) and back-linked via the entry’s derived_fact_ids — so a Q&A answer becomes reusable, discoverable knowledge rather than being buried in the history.

Return type:

str

refresh(mode='soft', *, ingest_fn=None, apply=True)[source]#

Refresh info from changed sources + undistilled Q&A.

ingest_fn(item) supplies extraction (intelligence is external); with apply=False the result is a non-destructive preview. See hired.candidate.refresh.

Return type:

RefreshReport

regenerate_synopsis()[source]#

Rebuild and persist a human-readable synopsis from current facts.

This is a projection — always derived from the fact store, never hand-edited — so it can be regenerated at any time without loss.

Return type:

str

save_upload(name, data)[source]#

Store a raw uploaded document by filename (see add_source()).

Return type:

None

sources()[source]#

Keys of all raw sources the candidate has provided.

Return type:

list[str]

supersede(old_fact_id, new_fact)[source]#

Replace old_fact_id with new_fact (invalidate, don’t delete).

Return type:

str

property synopsis: str#

The last persisted synopsis, regenerating it if absent.

topic(name)[source]#

Get-or-create the dossier for a subject (overview + optional files).

Return type:

TopicDossier

topics()[source]#

Slugs of all topic dossiers.

Return type:

list[str]