25 Commits

Author SHA1 Message Date
Timothy Kassis
204eef574c Add waypoint skill 2026-08-17 16:40:28 -07:00
Timothy Kassis
980e4f0bb2 Add CAD skill for lab hardware 2026-08-14 12:20:47 -07:00
Timothy Kassis
5ad4aae76b Update documentation and versioning for Agent Plugins compliance
- Enhanced AGENTS.md and CONTRIBUTING.md to clarify the structure and requirements for the Agent Plugins package, including the need for `plugin.json` to be schema-valid and version-synced with `pyproject.toml`.
- Updated README.md to reflect the new version 2.63.0 and added details about the repository being a portable Agent Plugins package.
- Added tests in test_repo_contract.py to ensure compliance with the Agent Plugins manifest schema and discoverability of skills.

This update ensures better adherence to the Agent Plugins standard and improves the overall documentation for contributors.
2026-08-11 17:44:32 -07:00
Andrey Fedorov
aaf763c3a6 Update imaging-data-commons skill from v1.4.0 to upstream v1.8.1
Rebased onto current main and re-synced from
ImagingDataCommons/imaging-data-commons-skill, which now holds SKILL.md under 500
lines upstream. references/core_capabilities.md is therefore removed rather than
refreshed: its content was redistributed into the topical guides that already own
each subject (sql_patterns, index_tables_guide, cli_guide, licensing_and_citation)
instead of a catch-all file, and upstream CI holds the budget so the split does not
have to be redone after each sync.

New since v1.4.0: the hosted IDC MCP server and REST API as first-class access paths
(references/mcp_guide.md, references/rest_api_guide.md), so a metadata question no
longer requires a ~77 MB idc-index install; licensing_and_citation.md; idc-index
0.12.5 / IDC data v24; scripts/check_version.py as the startup version check.

tests/imaging-data-commons/test_check_version.py covers the bundled script: offline,
standard library only, no idc-index needed. It is a copy of the upstream file, which
is written to be vendored — only two path constants and the frontmatter-version
assertion differ.

Verified: pytest tests/_meta tests/imaging-data-commons -> 29 passed, 1030 subtests;
skills-ref validate skills/imaging-data-commons -> valid; SKILL.md 495 lines.
2026-08-10 17:06:22 -04:00
neuroepithelial
550b965a69 Add bounded NCATS ARAX knowledge graph skill
Add a standard-library ARAX client for typed one-hop and endpoint-pinned two-hop Translator queries, selected-provider federation, entity normalization, and provenance-preserving artifacts. Include offline fixtures and tests, isolated test metadata, and README discovery.
2026-08-08 02:44:06 -04:00
Timothy Kassis
f8c6f0ef73 Introduced a new skill for relsa-severity-assessment 2026-08-07 12:08:05 -07:00
Timothy Kassis
d39264b47c citation-management: fix BibTeX corruption and metadata defects
The field parser in format_bibtex.py and validate_citations.py matched
`\{([^}]*)\}`, which stops at the first closing brace. Any title with a
protected term -- `{Highly accurate prediction with {AlphaFold}}` -- was
truncated mid-value, and rewriting it produced a .bib with unbalanced braces
that no BibTeX engine reads. extract_metadata.py emits that protection
deliberately, so the documented Phase 2 -> Phase 3 pipeline corrupted its own
output, and format_bibtex.py defaulted to overwriting the input in place.

Replace both parsers with a brace-depth scanner in scripts/_common.py, which
also owns entry rendering, page normalisation, and one citation-key scheme
shared by every producer -- entries from Crossref, PubMed, OpenAlex, and
Scholar now collide when they are the same paper, which is what makes
deduplication work at all. Writing is opt-in: without --output or --in-place
the result goes to stdout and the input is untouched.

Also fixed:

- pages: `replace('-', '--')` turned `583--589` into `583----589`; PubMed's
  abbreviated `1123-30` now expands to `1123--1130` rather than staying a
  range that resolves to nothing.
- publisher was read from Crossref and dropped by the writer, so every @book
  and @techreport failed the required-field check.
- an arXiv preprint with a DataCite DOI was typed @article with no journal --
  guaranteed to fail validation. It is @misc unless journal_ref names a venue.
- --url and PMCID were classified by identify_type but had no handler, so a
  publisher URL without a DOI in its path errored out. URLs now resolve via
  the citation_doi meta tag; PMCIDs via the NCBI ID converter.
- citation keys were unsanitised in search_pubmed.py: `Müller2021pmid123`
  and `O'Brien2021pmid124` are not valid BibTeX keys.
- DOIs were interpolated into API URLs unquoted.
- verify_doi used HEAD on doi.org, which follows to the publisher; several
  answer HEAD with 403 behind a bot check, so good DOIs looked unresolvable.
  Ask Crossref, then DataCite, and treat transport failures as unknown.
- valid_entries subtracted the error count from the entry count and reported
  `Valid entries: -2` for a one-entry file.
- structured abstracts kept only their first section; titles lost inline
  markup and carried PubMed's trailing full stop.
- two `note` fields could be emitted in one entry.
- --auto-fix was advertised in --help as "not implemented yet" and did nothing.
- venue_standards was assigned inside validate_file, so a fresh validator did
  not have it.

Add search_openalex.py: ~250M works, keyless REST API, cursor pagination,
abstracts rebuilt from the inverted index. The skill's own "single source
bias" pitfall previously had only two sources to offer, one of them scraped.

Drop the bundled schematic generators (1,148 lines) in favour of the
scientific-schematics skill, and update the shared-copy contract accordingly.

Reference-list length is editorial judgement, so a venue shortfall is now a
warning; only an explicit --min-count is enforced as an error.

Dependencies drop from eight packages to two: bibtexparser, biopython,
crossref-commons, pylatexenc, and selenium were declared but never imported,
and the parsing layer is now standard library.
2026-07-31 10:59:00 -07:00
Timothy Kassis
95d3adda6d market-research-reports: fix ledger validator crash on publication_date=not-stated
The sentinel "not-stated" is exactly 10 characters, so it satisfied the
len(publication) == 10 ISO-date guard and reached
date.fromisoformat("not-stated"), raising an uncaught ValueError instead of
the documented warning. SKILL.md instructs recording "not-stated" when the
publication date is unavailable, so this crashed on valid ledgers.

Check the sentinel before the retrieval/publication comparison, and add
regression tests for both the not-stated warning and the still-enforced
retrieval-precedes-publication error.

Fixes #219
2026-07-31 10:57:18 -07:00
Timothy Kassis
bd99c01e3f Update image generation and citation management scripts to use 'uv pip install' for package installations. Modify skill versions for infographics and generate-image to reflect recent changes. Enhance error handling and review logic in infographic generation scripts, ensuring better feedback on quality assessments. 2026-07-31 10:26:56 -07:00
Timothy Kassis
f1b60f8ef4 Update skill versions to 1.4 and 1.5 across multiple skills, including infographics, latex-posters, literature-review, scientific-schematics, and scientific-slides. Enhance API key resolution logic in various scripts to improve credential handling and error messaging. Adjust image model references for clarity in infographic and schematic generation scripts. 2026-07-28 17:32:42 -07:00
Timothy Kassis
4fb7e0bc29 Test every script-bearing skill, and enforce that it stays that way
AGENTS.md has always said that a skill shipping scripts/ puts its tests in
tests/<name>/, but nothing checked it: 54 of the 100 such skills had no suite
at all, including docx, pptx, xlsx, pdf and scanpy. All 100 now do.

tests/_meta is the guard. It runs the shared structural contract across every
skill in a single process -- safe because it parses scripts with ast and never
imports them -- and fails when a skill ships scripts/ without a suite or
without a [skills.<name>] entry in skill-requirements.toml. It needs no
scientific packages and finishes in seconds, so skill-tests.yml blocks every
pull request on it, plus the packages=[] suites.

tests/_contract holds what the per-skill suites were each reimplementing:
frontmatter conformance, the 500-line limit, no tests or bytecode under
skills/, local links resolving, scripts parsing, no eval/exec/os.system, no
standard-library shadowing, no hardcoded local paths, valid shell scripts. Also
the --help contract, which skips when a skill's packages are absent and runs
for real under --isolated, and shared behaviour for the files docx/pptx/xlsx
and five schematic-shipping skills carry byte-identical copies of, with drift
detection so they cannot diverge silently.

67 new suites, 3325 test functions. The existing suites were retrofitted: 18
no longer pin an exact skill version, so a version bump no longer breaks a
test; 11 duplicated structural methods removed; 19 wired to the --help
contract; and 5 that failed collection without their packages now skip
cleanly. run_all.py in the bare project environment goes from 6 failures to 0.

Writing the tests surfaced 19 defects in the skills, fixed here with version
bumps. The ones that changed scientific output:

  - openpiv reported vorticity 0 for a rotating flow, from a sign error in
    openpiv's y-up coordinate relabelling; solid-body rotation now gives 2w
    exactly, on grids of either orientation
  - deepchem returned solubility predictions in z-scored space while labelling
    them log(mol/L), because it transformed a y-less dataset instead of
    untransforming the output
  - neuropixels-analysis had the Allen and IBL ISI thresholds swapped,
    contradicting its own references/QUALITY_METRICS.md and inverting the two
    standards' relative strictness
  - scanpy's summarize() raised TypeError on every AnnData under anndata 0.13,
    which reports an unnamed None key on .layers; scanpy convert was broken
  - experimental-design's Latin hypercube was never reproducible: pyDOE3 draws
    from its own default_rng and ignores numpy's global seed
  - primekg shipped a hardcoded path naming a person, which is why
    no_personal_paths is now a contract rule

The remainder is upstream API drift, each verified against the installed
package: retired symbols in bioservices 1.16, gget helpers that returned lists
where a string was written, ArviZ 1.x kwargs in pymc, a positional-only
factory in pymoo, ReduceLROnPlateau(verbose=) in torch 2.13, a removed scvelo
parameter, and PyPDF2 in scientific-slides.

Two manifest environments could not build and are pinned: gget, where an
unpinned scanpy walked back to 1.9.8 and pulled llvmlite 0.36 which does not
compile on 3.13, and pymatgen, pinned to the snapshot its own _common.py
enforces rather than loosening that check. deepchem gains torch, without which
no model class exists.

python tests/run_all.py --isolated: 101 passed, 0 failed.
2026-07-28 10:20:12 -07:00
Timothy Kassis
4c90a52d54 Add pkpd-modeling skill
Pharmacokinetic and pharmacodynamic modelling and simulation: NCA,
compartmental fitting, population PK dataset validation, regimen
simulation, exposure-response, bioequivalence, allometric scaling and
first-in-human dose, ICH M12 drug-interaction prediction, and MAP
Bayesian therapeutic drug monitoring.

Linear mammillary models are solved analytically -- one eigendecomposition
of the rate matrix yields the impulse response, and each input type is a
closed-form convolution. This is far faster than an ODE solve inside a
fitter, keeps solver tolerance out of the objective function, and makes
the removable singularity at ka = -lambda (the flip-flop boundary) an
exact limit rather than a nan. Michaelis-Menten and TMDD, which have no
closed form, integrate with LSODA and apply doses by restarting at each
event.

Numerics are validated against results that do not depend on the
implementation: closed-form identities (AUC = D/CL, Vss, MRT, Bateman),
analytical profiles with known parameters that NCA and the fitter must
recover, the PowerTOST bioequivalence sample-size table (exact at six
CVs), the EMA ABEL cap, and the FDA body-surface-area conversion factors.
92 tests pass in an isolated numpy+scipy environment.

Documents current tooling verified against live sources rather than
recalled: Pharmpy 2.1.1 including the 2.0.0 row-index and 2.1.0
set_placebo_model breaking changes, NONMEM 7.6 ADVAN16/17, and the
2024-2025 status of ICH M12, M13A/B, E11A and FDA Project Optimus.
Provenance for every version- and date-specific claim is recorded in
references/source-ledger.md.
2026-07-27 18:38:01 -07:00
Timothy Kassis
061882ba79 Update paper-lookup to 2.0
Audited every documented endpoint against the live APIs and fixed what
came back wrong, then added the tooling for the failures that cannot be
fixed by documentation alone.

These APIs report failure with HTTP 200, which is the theme running
through most of this change:

- PMC eFetch returns a well-formed article with no <body> for non-OA
  content, with the reason only in an XML comment that parsers discard.
  This is the common case, not an edge case: eFetch full text covers the
  ~3M OA Subset out of ~10M articles.
- arXiv returns totalResults 1 and a single entry titled "Error" for a
  malformed parameter, and silently rewrites an unknown field prefix to
  all:, so a typo degrades a targeted search into a full-text one.
- bioRxiv/medRxiv /details/ pages are 30 records, not the documented 100,
  and an out-of-step cursor is accepted with a 200 -- a step-by-100 walk
  skipped records 30-99 of every hundred while looking successful.
- Europe PMC puts errCode in a 200 body.

Documentation fixes:

- Corrected bioRxiv/medRxiv page size and documented the per-endpoint
  messages shape, including why total (360) and count_new_papers (232)
  differ and which endpoints expose no counts at all.
- Percent-encoded the arXiv date-range brackets; the previous example
  made curl exit 3 (bad range specification) before sending anything.
- Documented the PMC non-OA hazard and added the PMC OA Web Service,
  which answers "is full text actually available" before the fetch.
- Corrected <arxiv:doi>: it is the journal DOI and is absent for papers
  that were never published. A constructed 10.48550/arXiv.{id} resolves
  at doi.org but 404s in both Crossref and OpenAlex, so it is not a
  portable key.
- Corrected the arXiv <id> scheme: entry ids are http:// while the links
  to the same pages are https://, inconsistent within one response.
- Flagged the /publisher/ example, which returns "no articles found" for
  valid prefixes, and the api.medrxiv.org host, which 500s on paths that
  api.biorxiv.org serves.
- Replaced the cross-platform fetch-tool table with a curl-first section
  that matches what allowed-tools actually grants.
- Removed stray tool-call markup from the end of SKILL.md.

Europe PMC (references/europepmc.md) closes a real gap: bioRxiv and
medRxiv have no keyword search of their own, and Europe PMC indexes both.
Its fullTextXML also 404s honestly where eFetch returns a bodyless 200.

scripts/ (standard library only) covers the logic that was being
re-derived per query, each exiting non-zero on a silent failure:
paginate.py (4 = unexplained shortfall), jats_to_text.py (2 = no <body>),
arxiv_atom.py (3 = error feed, 5 = throttled), openalex_abstract.py.
paginate.py redacts credentials from the provenance URLs it emits, since
OpenAlex and Crossref authenticate by query string.

tests/paper-lookup/ has 79 tests over fixtures captured from real
responses. arxiv_error.xml is reconstructed from a verified response
rather than saved from one, and says so -- arXiv penalizes repeated
malformed requests and stayed throttled.
2026-07-27 18:32:30 -07:00
Timothy Kassis
844f4a35cc Add analytical-method-validation skill
New skill for bench analytical scientists in regulated labs: planning,
evaluating, and documenting validation, verification, and transfer of
analytical procedures under whichever framework governs.

Frameworks. ICH Q2(R2) and Q14 and ICH M10 are encoded directly from their
openly licensed text, read from the adopted PDFs rather than from secondary
summaries. USP <1220>/<1225>/<1226>, the CLSI EP series, and ISO/IEC 17025 are
paywalled, so they are cited by designation and scope only and never
reproduced or reconstructed; edition numbers taken from listings rather than
the documents are marked for confirmation.

Q2(R2) content covers the restructured characteristics (range as the parent of
response and lower range limits), Table 1 tests by measured attribute, Table 2
reportable ranges, the recommended-data minima, and the 30 Nov 2023 error
correction. M10's chromatographic and ligand-binding-assay criteria are kept
strictly separate, including the LBA-only total-error limit and the differing
ISR tolerances.

Scripts. Six standard-library CLIs, no numpy and no network, computing the
statistics that decide fitness for purpose rather than the ones that look
reassuring:

- plan_validation.py         framework selection and a protocol whose
                             acceptance criteria must be pre-stated
- check_response.py          lack-of-fit F against pure error, residual runs
                             test, back-calculated error per level, and a
                             heteroscedasticity check for weighting
- check_accuracy_precision.py recovery with confidence intervals, and
                             precision decomposed per level into repeatability
                             and intermediate precision
- check_detection_limits.py  DL/QL by every approach Q2(R2) allows, compared
                             against the reporting threshold
- check_bioanalytical_run.py M10 run acceptance including the per-level QC rule
- compare_methods.py         Deming and Passing-Bablok regression plus TOST
                             equivalence against a pre-stated margin

Distributions are built from the regularised incomplete beta and gamma
functions and checked against published quantiles.

Scope. The skill reports and computes. It does not decide that a procedure is
validated, accept or reject a run, close an investigation, or replace the
analyst, technical reviewer, quality unit, or regulator.

Also adds 111 tests in tests/analytical-method-validation, a docs/skills.md
entry, examples.md Example 36b, and updates the README skill count to 156.
2026-07-27 16:34:28 -07:00
Timothy Kassis
e608baad6e Add pathogen-variant-surveillance skill
Query live pathogen genomic surveillance through the GenSpectrum LAPIS
API: which viral lineages are circulating now, how fast they are
growing, and what mutations they carry. Covers 15 instances spanning
SARS-CoV-2, influenza A (including H5N1 and the seasonal H3N2/H1N1pdm
clades), and the Pathoplexus organisms.

This is a class of question large models answer confidently and wrongly.
Lineage names post-date training; the nomenclature is a live data
structure rather than a convention (XFG only resolves through
alias_key.json); and 294 of the ~6,230 designated names have been
withdrawn or redesignated, so remembered facts are not merely stale.

Four standard-library CLIs, no API key:

  resolve_lineage.py     is this name still valid, what does it expand
                         to, what is it descended from
  lineage_prevalence.py  discover the top lineages in a window, then
                         weekly prevalence with Wilson intervals,
                         coverage flags, and a guarded growth fit
  mutation_profile.py    defining mutations, or a diff between two
                         lineages, for assay-match questions
  reporting_lag.py       measure how long sequences take to arrive and
                         derive a trust cutoff

Nothing hardcodes a field name. Schemas differ materially between
instances -- dateFrom is correct on SARS-CoV-2 and a hard 400 on H5N1 --
so every script reads /sample/databaseConfig and picks the collection,
submission, and lineage columns from what the instance declares.

The API traps documented in references/lapis-api.md were all verified
against the live services. The sharpest: a trailing '*' expands to
descendants only where the column carries a lineage index. pangoLineage=
XFG returns 4 and XFG* returns 640; on H5N1, clade=2.3.4.4b returns
62413 and clade=2.3.4.4b* returns 0. Silently wrong in both directions,
so lineage_filter() refuses to build the query that lies.

Two statistical guards, both prompted by wrong output during testing.
A lineage observed zero times in every week produced a confident
+0.105/week slope from the continuity correction alone as the
denominator shrank; growth fits now require real observations. And the
quasi-binomial dispersion is floored at 1, since an estimate below the
model's own scale reports an interval narrower than binomial sampling
allows.

117 tests, including live checks gated behind LAPIS_LIVE_TESTS=1 that
document the API behaviour the scripts were built against.
2026-07-27 15:40:33 -07:00
Timothy Kassis
6d22863f8d Replace iso-13485-certification with iso-standards-readiness
Fold the ISO 13485 skill into an umbrella standards-readiness skill so a
single skill covers several standards instead of one skill per standard
competing for selection on every compliance-adjacent prompt.

SKILL.md becomes a router: boundary, ISO/IEC copyright rules, current
baseline, assurance-lane discipline, the shared workflow, and the CLI
contract. Per-standard depth moves into references/.

Covers four standards in this version:

- ISO 13485 medical device QMS (certification lane)
- ISO 14971 device risk management (no lane of its own)
- ISO/IEC 17025 testing and calibration laboratories (accreditation)
- ISO 15189 medical laboratories (accreditation)

_catalog.py becomes a StandardProfile registry. Each profile carries its
own process domains, scope-activity vocabulary, and scope-item fields.
validate_scope_intake, validate_evidence_manifest, and gap_analyzer take
--standard; argparse choices refuse an unlisted value with exit 2 rather
than defaulting. audit_document_records, check_capa, and
check_supplier_controls were already standard-agnostic; check_traceability
and check_qmsr_transition stay device-specific.

New references/assurance-lanes.md exists because lane confusion, not
missing documents, causes most substantive errors in this work:
laboratories are accredited and not certified, ISO 15189 accreditation
does not satisfy CLIA, and ISO 14971 has no certificate at all.

The source ledger adds entries for ISO/IEC 17025, ISO 15189, ISO/TR
24971, the GLOBAC transition, ILAC P10/G8, and the CMS CLIA lane. ISO
catalogue metadata gathered on 2026-07-26 is marked [confirm on iso.org],
since iso.org refused automated access and those entries came from
secondary summaries.

Also adds laboratory and medical-laboratory scope-intake templates, both
fail-closed, and updates docs/skills.md and docs/examples.md so the
catalog links do not 404.

Verified: skills-ref validate passes for this skill and all others; 20
tests and 23 subtests pass directly and under run_all.py --isolated;
security scan clean (1 LOW, no HIGH+). The LOW finding is a pre-existing
unreachable assert in _common.py, verified rather than "fixed".
2026-07-26 16:26:52 -07:00
Timothy Kassis
3f530cf49e Update generate-image for the OpenRouter Image API
The skill called /api/v1/chat/completions with modalities: ["image","text"],
which reaches only 11 models. Both FLUX models the skill documented as options
are not among them, so those paths returned 404 "No endpoints found that
support the requested output modalities". Move to POST /api/v1/images, which
serves the full 38-model image catalogue.

- Parse data[].b64_json and media_type instead of
  choices[].message.images[].image_url.url; output extension now follows the
  returned media type, so vector models write .svg correctly.
- Send reference images as input_references; -i is repeatable for compositing.
- Add --n, --aspect-ratio, --resolution, --size, --quality, --output-format,
  --background, --output-compression, --seed, --timeout, --list-models.
- Omit unset parameters. Models reject unsupported parameters rather than
  ignoring them, so a fixed parameter set breaks most of the catalogue.
- Fix API key resolution: check_env_file() only read .env files, so the
  documented `export OPENROUTER_API_KEY=...` never worked. Order is now
  --api-key, environment, .env.
- Default to google/gemini-3.1-flash-image (GA) rather than the preview slug.
- Drop the requests dependency for stdlib urllib.

Add references/models.md with per-model parameter support, reference-image
limits, and n caps. Add tests/generate-image/ with 27 network-free tests.

Verified against the live API: default model at 16:9, flux.2-pro with --seed
and --output-format, and an -i edit all produce correct images; --list-models
returns 38 models without a key.
2026-07-26 15:48:58 -07:00
Timothy Kassis
ce67928122 Add genomic-coordinates skill
Covers the conventions that produce silent off-by-one and wrong-assembly
errors: 0-based half-open vs 1-based inclusive across BED/GFF/VCF/SAM and
friends, VCF indel anchoring and left-alignment, GRCh37 vs hg19 vs GRCh38
vs T2T, and genomic-to-transcript-to-CDS-to-protein positions.

Four standard-library scripts, no network:

- convert_coords.py    intervals between 21 conventions
- normalize_variant.py trim and left-align against a reference, compare
                       two representations for equivalence
- check_contigs.py     identify the assembly, report why two files
                       will not join
- audit_intervals.py   scan a BED/GTF/GFF3/VCF for convention violations

Build signatures are read from the UCSC chrom.sizes files and the NCBI
GRCh37.p13 assembly report; region-string semantics follow the samtools
manual, including that REF:START runs to the end of the contig and that
GRCh38 HLA contig names need htslib brace quoting.
2026-07-26 15:33:36 -07:00
Timothy Kassis
cca1e05ddf Add uncertainty-and-units skill under skills/uncertainty-and-units
Metrology skill covering units and measurement uncertainty, with six
standard-library-first CLIs that run offline:

- propagate_uncertainty.py: GUM framework and Monte Carlo on the same
  model, with the JCGM 101 clause 8 linearization check
- uncertainty_budget.py: components stated the way certificates state
  them, Welch-Satterthwaite effective dof, coverage factor from t
- format_result.py: round the uncertainty first, then the value to the
  same decimal place; plus-minus, concise, and ASCII forms
- convert_units.py: pint conversion including context-only relations,
  with the uncertainty carried through the local derivative
- audit_units.py: static scan for silent unit and uncertainty defects
  (UNIT001-004, UNC001-004, CONST001) with suppression directives
- check_plausibility.py: 14 dimensionless groups, 8 characteristic
  scales, and 22 cited magnitude bands, each dimensionality-checked
  before any number is reported

Measurement models are parsed to an AST and reduced by an explicit walk;
nothing is compiled or executed. Physical constants come from
scipy.constants at run time rather than from literals.

Tests in tests/uncertainty-and-units/ (85 cases) verify the metrology
against published values and assert every bundled script passes the
skill's own auditor with no findings.
2026-07-26 15:08:29 -07:00
Timothy Kassis
87b598a51a Add ontology-term-resolution skill
Resolve free-text scientific labels to ontology term IDs and validate
existing CURIEs against the EBI Ontology Lookup Service (OLS4). Covers the
concepts whose identifiers are routinely invented rather than looked up:
tissue, cell type, disease, phenotype, assay, chemical, organism, sex, and
developmental stage.

Two stdlib-only scripts, one per direction:

  resolve_terms.py   text -> ID, escalating exact -> token -> fulltext and
                     labelling every hit exact_label / exact_synonym /
                     partial, so a fuzzy guess cannot pass as a match
  validate_terms.py  ID -> verdict (not_found, obsolete + replacement,
                     label_mismatch, wrong_ontology, wrong_branch), exiting
                     non-zero so it works as a CI gate on a metadata file

Behaviour verified against the live service, and the reason the skill ships
scripts rather than a recipe:

- exact=true is exact *token* matching, not exact label: "liver" returns 161
  hits in UBERON, 1 once queryFields is restricted to label
- /search never returns is_obsolete or term_replaced_by, even when they are
  named in fieldList, so only term detail can answer whether an ID is current
- ontology=efo returns MONDO and CL hits, because ontologies import each other
- the obo_id index has holes: MONDO:0000001 is live and defined by MONDO but
  unindexed, so an IRI fallback is needed to avoid a false not_found
- IRIs are not all OBO PURLs; EFO and Orphanet use their own namespaces
- OxO is retired and serves HTML with HTTP 200
- a branch check does not exclude cell types from anatomy, since CARO places
  cell under anatomical structure

Tests: 59 in tests/ontology-term-resolution, 53 offline with stubbed network
plus 6 live smoke tests gated behind OLS_LIVE_TESTS=1 that pin the API
behaviour above.
2026-07-26 14:45:44 -07:00
Timothy Kassis
b80fcda721 Enhance skill environment management and documentation
- Updated AGENTS.md and CONTRIBUTING.md to clarify the use of isolated environments for each skill, addressing dependency conflicts and ensuring proper testing setups.
- Modified tests/run_all.py to implement the `--isolated` flag, allowing for the creation of throwaway environments per skill based on `tests/skill-requirements.toml`.
- Improved handling of unavailable packages and added detailed instructions for contributors on managing skill dependencies.
2026-07-26 13:58:18 -07:00
Timothy Kassis
2f2022de18 Update documentation and improve test structure for autoskill
- Enhanced AGENTS.md to clarify skill scope and directory structure, providing clearer guidelines for skill creation and updates.
- Updated CONTRIBUTING.md to emphasize the separation of tests from skill directories, ensuring better organization and clarity for contributors.
- Revised .gitignore to include .pytest_cache, improving project cleanliness.
- Adjusted pyproject.toml to configure pytest for better test path management.
- Incremented version number in SKILL.md for autoskill to reflect recent updates.
2026-07-26 09:54:14 -07:00
Timothy Kassis
8cb0f52a35 Add initial test suite for autoskill functionality
- Introduced a comprehensive test suite for the autoskill project, including tests for backends, CLI commands, and various skill functionalities.
- Added smoke tests for LM Studio integration to validate real-time interactions.
- Implemented tests for session clustering and event fetching to ensure accurate data handling.
- Established a framework for skill description loading and matching, enhancing the robustness of skill management.
- Included redaction tests to verify sensitive information is properly handled in outputs.
- Created end-to-end tests to simulate the full autoskill pipeline, ensuring all components work together seamlessly.
2026-07-26 09:54:05 -07:00
Timothy Kassis
fc0b9f6924 Enhance Research Lookup Skill: Update documentation and improve backend routing for manuscript evidence compilation. The skill now targets 60 verified references, producing structured research packets. Adjusted descriptions in README and SKILL.md for clarity, and removed outdated test file. 2026-07-13 17:25:07 -07:00
Bortlesboat
b82768fd53 add missing research grants references 2026-05-05 13:42:59 -04:00