From cogni-projects
This skill should be used when the user wants a ranked shortlist of consultants for the open roles on a cogni-projects portfolio — the staffing match engine (whether the ask comes from a partner, a delivery lead, or consulting ops). Trigger on: "staff this project", "who should I put on", "recommend consultants for", "staffing recommendations", "match consultants to roles", "rank candidates for the open roles", "who is available for", "build a staffing shortlist", or any request to turn a cogni-projects portfolio's consultants and projects into a ranked candidate list per open role — even if the user does not name the portfolio.
How this skill is triggered — by the user, by Claude, or both
Slash command
/cogni-projects:projects-staffThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Turn a cogni-projects portfolio into a ranked staffing shortlist: for every open
Turn a cogni-projects portfolio into a ranked staffing shortlist: for every open
role on every project, a list of candidate consultants each showing three
visible sub-scores — availability and profile fit, which rank the
candidates within a role, plus strategic impact, a project attribute shown
per candidate that orders the projects themselves. It reads the consultant and
project records authored by projects-entities and produces the recommendation
a partner defends a staffing call with. Existing assignments are not yet
netted out of a consultant's capacity — headroom comes from the consultant's
allocation_pct field alone (netting out live assignments is a later child).
The ranking is computed by a deterministic script — scripts/staffing-score.py
— so the same portfolio always yields the same shortlist. The skill's job is to
locate the portfolio, run the scorer, and render its JSON into a human-readable
recommendation artifact.
For each project that carries open_roles, the scorer ranks candidate
consultants per role. Each candidate carries three sub-scores in [0,1], all
shown separately; the combined score that orders the shortlist within a role
blends the two genuine per-candidate factors — availability and profile fit:
available_from/available_until
window overlaps the project's start_date/end_date, weighted by free
capacity (allocation_pct headroom). A consultant whose window does not
overlap the project window is excluded from that project's ranking entirely.skills match the open role label,
blended with a seniority prior.strategic_impact (1–5) normalized. This
is a project attribute, identical for every candidate of a role, so it does
not reorder candidates within a role. Instead it orders the projects
themselves: firm-defining projects and their open roles surface first in the
output. The sub-score stays displayed per candidate for context.The full field contract these read lives in
../../references/data-model.md. The scorer
returns the repo-standard {"success", "data", "error"} JSON and never bakes a
wall-clock value into a score, so its output is reproducible.
Find the portfolio directory the user means. If they name a slug, use
cogni-projects/<portfolio-slug>/. Otherwise glob
cogni-projects/*/projects-portfolio.json and, when more than one portfolio
exists, ask which one. If none exists, tell the user to run
/cogni-projects:projects-setup first and author entities with
/cogni-projects:projects-entities — this skill scores an existing portfolio, it
does not scaffold or populate one.
A portfolio with zero projects carrying open_roles, or zero consultants, is a
valid but empty input: the scorer returns success: true with an empty ranking.
Say so rather than treating it as an error — the fix is to author more entities,
not to debug the skill.
Run staffing-score.py against the portfolio directory and capture its JSON:
python3 "${CLAUDE_PLUGIN_ROOT:-$(ls -td "$HOME"/.claude/plugins/cache/*/cogni-projects/*/ 2>/dev/null | head -1)}/scripts/staffing-score.py" "cogni-projects/<portfolio-slug>"
It returns {"success", "data", "error"} (exit 0 ok / 1 domain failure / 2
usage). On success: false, surface error to the user and stop. A domain
failure (exit 1) usually means the portfolio directory or its manifest is
unreadable — but an error naming validate-entities.py instead means a
broken or partial plugin install, not a portfolio-data problem; say so rather
than pointing the user at their entities. On success, data.projects[] holds
only the non-closed projects (closed projects are skipped) and, per project, an
open_roles[] array where each role carries a candidates[] list already ranked
by combined score (best first) and a per-role excluded_count of consultants
dropped for no availability overlap with that project's window.
Render the scorer JSON into a human-readable markdown artifact at
cogni-projects/<portfolio-slug>/staffing-recommendations.md, and write the raw
scorer JSON alongside it at
cogni-projects/<portfolio-slug>/.metadata/staffing-recommendations.json (the
machine-readable record the backfilling recommender and partner-meeting dashboard
later read).
The markdown artifact has one section per project, and within it one table per open role. Show the three sub-scores separately — that per-factor breakdown is the point of the engine (a partner needs it to defend the call), never collapse it to a single opaque number:
The heading shows the raw strategic_impact (projects[].strategic_impact,
1–5); the table's Strategic impact column shows the normalized [0,1] value
(candidates[].scores.strategic_impact). Key the null/em-dash decision on the
raw projects[].strategic_impact being null — the normalized
scores.strategic_impact is 0.0 (not null) for both an absent value and a raw
1, so it cannot distinguish "missing" from "tactical". When the raw value is
null, render an em dash (—) in both the heading and the column rather than
0/5. The other four columns map to
candidates[].scores.{availability, profile_fit, combined} and the consultant's
name/consultant slug:
# Staffing recommendations — <portfolio name>
## <Project name> (`<project-slug>`) — strategic impact <n>/5 (or "— —" when null)
### Role: `<role>`
| Rank | Consultant | Availability | Profile fit | Strategic impact | Combined |
|------|-----------|-------------|-------------|------------------|----------|
| 1 | <name> (`<slug>`) | 0.84 | 0.53 | 0.75 | 0.70 |
| 2 | … | … | … | … | … |
_<excluded_count> consultant(s) excluded from this role — no availability
overlap with the project window. Exclusion is a project-window property, so the
same consultant may be excluded from every role of the project and counts once
per role._
Preserve the scorer's ordering — both the project/role order (projects come strategic-impact-first, so firm-defining work leads the recommendation) and the candidate order within each role — do not re-sort. When a role has zero candidates (everyone excluded), say so under its heading instead of rendering an empty table.
projects-setup seeds cogni-projects/<portfolio-slug>/.metadata/staffing-log.json
as an object with a matches array: {"matches": []}. Read that file, append
one record to its matches[] array, and write it back — preserve the envelope,
never overwrite it with a bare array. Only if the file is genuinely absent,
create it with that exact {"matches": []} shape first.
Each record captures this run: portfolio (the slug), consultant_count,
project_count, ranked_candidate_count (copied from data), and
artifact_path (the staffing-recommendations.md path). This is the append-only
audit trail that later skills and the dashboard scan.
Report the artifact path, how many projects and open roles were scored, and the
top candidate for each open role (name + combined score). Keep it short. If any
role came back with everyone excluded, call that out — it usually means no
consultant's availability window overlaps that project, which is a portfolio-data
gap to fix with /cogni-projects:projects-entities, not a scoring bug.
scripts/staffing-score.py, not this skill.{success, data, error} JSON, stdlib-only — no pip
dependencies. staffing-score.py reuses validate-entities.py's frontmatter
parser rather than adding its own.available_from / available_until / allocation_pct), not a
separate entity — consistent with the data model.npx claudepluginhub cogni-work/insight-wave --plugin cogni-projectsThis skill should be used when the user wants to author or register a consultant, project, or assignment record in a cogni-projects portfolio — the entities the staffing engine scores over. Trigger on: "add a consultant", "add a project", "create an assignment", "author a projects entity", "register a consultant/project", "record a staffing assignment", "populate the projects portfolio", or any request to write consultant/project/assignment data into a cogni-projects portfolio — even if the user does not name the entity type.
Resumes portfolio projects by discovering project state, surfacing progress, and recommending next steps. Useful for multi-session portfolio work.
Provides enterprise project management capabilities: portfolio optimization, quantitative risk analysis (EMV, Monte Carlo), resource planning, and executive reporting for software/SaaS/digital transformation initiatives.