Skip to content

Feat/recruitment navigator gaps#10

Merged
JamesKane merged 2 commits into
mainfrom
feat/recruitment-navigator-gaps
Jun 20, 2026
Merged

Feat/recruitment navigator gaps#10
JamesKane merged 2 commits into
mainfrom
feat/recruitment-navigator-gaps

Conversation

@JamesKane

Copy link
Copy Markdown
Owner

No description provided.

JamesKane and others added 2 commits June 20, 2026 16:03
The recruitment engine + web UI existed but had no signed-Edge API, so the
Navigator edge couldn't participate. Add the response-side endpoints the
Navigator needs:

- du_db::recruitment::messages: canonical signing strings (poll / respond),
  mirrored byte-for-byte by navigator-sync.
- routes/recruitment_edge.rs (mirrors social_edge): signed
  GET /api/v1/recruitment/invitations (the caller's open INVITED invitations)
  and POST /api/v1/recruitment/respond (accept/decline; notifies the campaign
  owner on accept). Registered in routes/mod.rs.
- DB-gated end-to-end test: an invited did:key polls + accepts → ACCEPTED, and
  a forged signature is rejected.

Respond-only: campaign creation stays on the web flow (it's gated to a
group_project admin) until the groupProject-PDS bridge lands. PII-free — a DID,
a signature, and the accept/decline choice.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ts, accept award, deep-link kind

Close the four follow-up gaps left after the social-layer orchestration round.
Each turned out to need an AppView/web piece, not just Navigator work:

- Navigator-native campaign creation: add du_db::research::recruitable_projects
  (projects_for_member filtered by ManageSubjects) + signed Edge endpoints
  GET /api/v1/recruitment/projects and POST /api/v1/recruitment/campaign.
  Factor the create→compute_cohort→deliver→notify orchestration into a shared
  create_and_deliver so web and Edge can't drift. (PDS groupProject bridge
  deferred — the signed listing keys off DID membership and needs no PDS record.)

- Subclade cohort expansion: compute_cohort now resolves the target via the tree
  and matches against the whole subtree's node names (ANY), falling back to the
  literal-string match when the target isn't placed (off-tree calls still recruit).

- RECRUITMENT_ACCEPTED award: wire reputation::record_event on a fresh acceptance
  in both web and Edge respond (via shared on_acceptance). respond() already only
  flips an INVITED row once, so this fires exactly once per member — no farming.

- Notification deep-link: give invitations their own RECRUITMENT_INVITE kind
  (link=/recruitment/{cid}) so the Navigator recognizes them and routes straight
  to its invitations section (campaign id is BIGINT, can't ride the UUID related_id).

No migrations. Tests: subclade expansion (3-deep chain + off-tree fallback) and
the Edge projects-list/create path (signed, ManageSubjects-gated, invite delivered).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@JamesKane JamesKane merged commit c665f19 into main Jun 20, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant