Skip to main content

Career Kb

@magistr/career-kbv2026.08.19.1· 27d agoMODELSSKILLS
01README

Retrieval, routing, and triage over a career-research knowledge base — 22 career-psychology extractions (1 practitioner AMA + 21 academic papers) across the ama, inaction, and success-outcomes clusters, each with YAML frontmatter (title, topics, key_constructs, summary) and a standardized section layout. The corpus ships as bundled reference files (read at runtime via context.extensionFile), so the model is self-contained and needs no configuration.

Methods:

  • index — scan the cluster folders and build a queryable catalog from frontmatter
  • search — route a question or keywords to the most relevant sources (optional cluster filter)
  • read — return a source's frontmatter plus its full body or one named section
  • assess — triage a described situation into its problem family (inaction / indecision / indecisiveness / success-derailer / shock-transition), name the validated instrument (CARINAS, SCCI, EPCD), point to the sources to read, and give coping guidance; optionally score self-rated CARINAS items against published benchmarks

Ships the career skill for routing career questions to grounded sources.

02Models1
@magistr/career-kbv2026.08.19.1extensions/models/career_kb.ts

Global Arguments

ArgumentTypeDescription
clustersarrayOptional filter restricting index/search to these bundled clusters.
maxFileBytesnumberMax bytes for any single bundled reference file read; larger files are rejected.
fn index()
Build the catalog of all bundled sources (idempotent — overwrites the latest catalog).
fn search(query: string, cluster?: string, topK?: number)
Route a question or keyword query to the most relevant sources, ranked. Optionally filter by cluster.
ArgumentTypeDescription
querystringA question or keywords to route
cluster?stringRestrict to one cluster: ama | inaction | success-outcomes
topK?numberHow many hits to return (default 6)
fn read(file: string, section?: string)
Read one source: its frontmatter plus the full body, or just a named section (e.g. Measurement, Frameworks). The returned content is raw markdown -- untrusted; callers MUST sanitize/escape before rendering it as HTML.
ArgumentTypeDescription
filestringRelative path (inaction/career-inaction.md), filename, or slug
section?stringOptional section name to extract (case-insensitive, partial match)
fn assess(situation: string, carinas?: array)
Triage a described career situation: classify it across the KB's problem families (inaction / indecision / indecisiveness / success-derailer / shock-transition), name the validated instrument for each, point to sources, and give coping guidance. Optionally score self-rated CARINAS items.
ArgumentTypeDescription
situationstringFree-text description of the career situation to triage
carinas?arrayOptional self-ratings for the 8 CARINAS items, each 1–5 (see inaction/career-inaction-scale.md for the items)

Resources

catalog(infinite)— Queryable catalog of every career-research source: cluster, title, topics, key constructs, summary, and section list, built from frontmatter.
searchResult(infinite)— Ranked sources matching a question or keyword query, with matched terms and a why-string.
document(infinite)— A single source's frontmatter plus its full body or one requested section.
assessment(infinite)— Triage of a described career situation: which problem family/families it fits, the validated instrument for each, sources to read, and coping guidance.
03Skills1
career1 file
04Previous Versions4
2026.08.02.1

2026.08.02.1

Real-fixes the six remaining latent bugs (LB2-LB7) characterized by the test backfill and pinned in 2026.07.16.2, tracked and resolved via the local career-kb-latent-bugs issue-lifecycle model (NEVER filed to the swamp.club Lab). LB1 (path traversal, fixed in 2026.08.01.1) is untouched and both its pins stay green. All fixes converge on one chokepoint per bug; the contract-fixture suite (career_kb_test.ts) and the methods suite (career_kb_methods_test.ts) are byte-identical to 2026.08.01.1.

  • LB2 (MEDIUM) all-out-of-range CARINAS -> NaN mean mislabeled "high": assess's CARINAS branch now guards vals.length === 0 and reports a distinct { mean: null, band: "no valid input", interpretation: "..." } state instead of letting 0/0 = NaN fall through every < comparison into the STRONGEST band. AssessmentSchema.carinas.mean widened to z.number().nullable() (backward-compatible; existing numeric-mean resources stay valid).
  • LB3 (MEDIUM) resource-name slug collision across search/assess/read: added shortHash() (FNV-1a-32, base36) and resourceName() (a slugify() prefix plus a shortHash() suffix over the full input) next to slugify; search/read/assess now key their written resource on resourceName(...) instead of slugify(...), so distinct inputs that slugify alone would collapse no longer collide, while identical input still yields an identical name (idempotent overwrite preserved). Charset stays [a-z0-9-], length stays <= 48.
  • LB4 (MEDIUM) one bad/missing source aborts the whole catalog build: loadSources now reads each entry inside a try/catch; a failure is console.warn'd and skipped instead of aborting index()/search()/bare- slug read() entirely -- the catalog (or search pool) still covers every source that DID load.
  • LB5 (LOW) empty clusters: [] disabled filtering entirely: sourceList now branches on clusters.length directly (not clusters && clusters.length ? filter : index), so an explicit empty array matches zero sources, as its shape implies, instead of falling back to the full unfiltered index. The undefined branch (returning the full index) is defensive only -- the schema default means clusters is never actually undefined at runtime.
  • LB6 (LOW) no size cap on read()/index(): added a defaulted global arg maxFileBytes (default 1,000,000, safely above the largest real source ~20 KB). readRef now calls Deno.stat() before Deno.readTextFile() and throws a clear error naming the file and its size when it exceeds the cap.
  • LB7 (LOW/info) verbatim unsanitized content storage -- BY DESIGN: decided lossless-by-design (this model returns source markdown to an agent/LLM consumer, not a trusted-HTML renderer -- stripping markup would corrupt legitimate research content) and made the contract explicit and testable: DocumentSchema.content gets a .describe(...) naming it untrusted-must-sanitize, and read's method description carries the same caveat. No change to stored bytes.
  • Bumped manifest.yaml and model.version to CalVer 2026.08.02.1. Added an identity upgrades[] entry (fromVersion: "2026.08.01.1") -- the sole new global arg (maxFileBytes) is defaulted (schema fills it at parse time for existing instances) and no new resource-schema field was added (LB2 widens an existing field to nullable; LB7 adds field metadata only), so upgradeAttributes: (old) => old is correct.
  • Flipped the LB2/LB3/LB4/LB5/LB6 pins in career_kb_adversarial_test.ts from characterizing the bug to asserting the fixed behavior (each renamed with -- FIXED), re-framed the LB7 pin to assert BOTH lossless preservation AND the documented untrusted-content contract (renamed -- BY DESIGN), and added new both-side/resilience tests: LB2 (all-out-of-range and one-in-range-among-out-of-range, in career_kb_coverage_test.ts), LB3 (determinism, distinctness, charset+length of resourceName/shortHash, in career_kb_coverage_test.ts), LB4 (search() resilience over the same one-bad-two-good corpus, in career_kb_adversarial_test.ts), LB6 (a positive under-cap read, and an index() run over one oversized + one small entry that synergizes with the LB4 fix, both in career_kb_adversarial_test.ts). Updated the "refuted: globalArguments carries no secret-shaped field" test to the new two-key shape (["clusters", "maxFileBytes"]) -- the one intentional non-byte-identical change to an otherwise-frozen negative test, driven by the legitimate maxFileBytes schema extension. Flipped the property suite's (e)

Notes trimmed at a line boundary to fit the registry's 4900-byte per-version cap. Full section: https://github.com/umag/swamp-workspace/blob/d850d8e8372d4c0008c9245959a090b37095de7a/career-kb/CHANGELOG.md

2026.08.01.1

2026.08.01.1

Fixes the HIGH latent bug characterized (pinned, not fixed) by the test backfill below, tracked and resolved via the local career-kb-latent-bugs issue-lifecycle model:

  • Path traversal via read's file argument (HIGH): when file contained a /, it flowed verbatim through readRef() into context.extensionFile(references/${rel}) then Deno.readTextFile(...) with zero sanitization, so a value with .. segments (e.g. ../outside/some-file.md) escaped the references/ directory into a sibling directory. Added a pure assertWithinRefs(rel) guard (next to slugify in the Helpers section) that rejects absolute paths (leading /), any .././empty path segment, and backslashes, and calls it at the single readRef() chokepoint BEFORE building the on-disk path -- this confines read, loadRaw, loadSources, and sourceList in one place, independent of (and regardless of) any downstream context.extensionFile confinement, as defense in depth. Legitimate cluster/file.md relative reads and the bare index.json lookup are unaffected.
  • Bumped manifest.yaml and model.version to CalVer 2026.08.01.1, in sync.
  • Flipped the LB1 pin in career_kb_adversarial_test.ts from success-characterization to assertRejects (asserting zero resource writes on rejection), and added a second pin for four extra synthetic traversal shapes (absolute /etc/passwd, nested ../.., mixed a/../../b, ./x) -- both assert the rejection is the guard's own "Invalid reference path" message specifically (not an incidental filesystem error), verified genuinely RED against the unmodified source before the guard was wired in. Added focused unit tests for assertWithinRefs in career_kb_test.ts (accepts inaction/career-inaction.md and index.json; rejects ../x, /etc/passwd, a/../../b, ./x, and a backslash variant, naming the offending input in each thrown message). The committed fixtures/outside/fixture-escape-target.md stays as the now-unreachable synthetic attack target. LB2-LB7 pins are unchanged -- they remain deferred and still characterize current behavior, still tracked by the local career-kb-latent-bugs issue-lifecycle model (NEVER filed to the swamp.club Lab).
2026.07.16.2

Release 2026.07.16.2 — align model versions with manifests

Maintenance release across the @magistr extensions. For most packages this carries no functional change: the only edit is the model's version: field, brought back in line with its manifest version so the published model type version and the package version no longer drift.

Functional changes in this release are limited to:

  • anime-cron: normalizeTitle now strips a ": subtitle" suffix and a trailing parenthesized year before comparison, fixing dedup false-misses where the torrent title carries a subtitle or year that the AniList romaji does not.

  • arckit: first publish. Standalone ArcKit port — a 12-phase architecture governance state machine with 65 bundled templates, driven by a bundled skill.

Also tracks three extensions (kaiten, observability-agent, music-library) that previously existed only as untracked working-tree directories, recovered from stashes.

2026.06.29.1

Merge pull request #37 from umag/feat/career-kb-extension

Add @magistr/career-kb extension

05Stats
A
100 / 100
Downloads
0
Archive size
150.2 KB
  • Has README or module doc2/2earned
  • README has a code example1/1earned
  • README is substantive1/1earned
  • Most symbols documented1/1earned
  • No slow types (deprecated)1/1earned
  • Dependencies pass trust audit2/2earned
  • Has description1/1earned
  • Platform support declared (or universal)2/2earned
  • License declared1/1earned
  • Verified public repository2/2earned
06Platforms
07Labels