"A person reads it" reassures about process (a human, not a bot) but
never answers what an applicant actually wants to know: does what I
specifically bring matter here? Rewrote to say that directly, and
named how it gets used once they're in - dialogue-centered
development, not a queue of pre-decided tasks.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Bucket names describe content, not their relation to portal:
portal_applicants -> applicants, portal_subscribers -> subscribers,
portal_project_inquiries -> projects. ResourceSpec's `bucket:` field
becomes `source: {kind: kv, bucket: ...}` to match portal's new
generalized ResourceSource schema.
The project-inquiry alternative now also shows a live "what we've
built" showcase (a gitea_starred resource, jq-shaped) and asks who the
work is for (organization/contact fields) - b2b framing. Review desk's
"Inquiries" -> "Projects", transitions to accepted/declined instead of
a generic "handled".
Front page gets a `responsible` contact for the "report this question"
mechanism.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Per feedback: sending a newsletter is naturally part of "Subscribers",
not a separate review task. Also fixes a real bug - the standalone
Compose newsletter alternative had no `action`, so AlternativeCard
never rendered a submit button/form for it at all (has_action gates
the <form>, unconditionally). action: /review reloads the dashboard
after sending.
- index.yaml: record_as on "I want something built" and "Keep me
posted" - those submissions previously only existed as a NATS
event, nothing durable, despite promising a reply/subscription.
- review.yaml: consolidated into one dashboard question with four
alternatives (Applicants, Inquiries, Subscribers, Compose
newsletter) rather than separate pages per resource.
- Compose newsletter has no record_as/resource of its own - an
automation (n8n) filters portal.answers.submitted directly for
question_id == "/review" && alternative == "Compose newsletter",
matching events.rs's own "gain a second subscriber" design.
- lint.sh: allow type: prosekit (the new rich-text requirement kind).
Validates YAML/required fields/duplicate ids/requirement types with
yq+jq against the exact shape content.rs parses (not a full schema
check - that would mean building portal just to lint content), then
publishes portal.content.reload over NATS so every running portal
instance picks up the change without a restart (portal's own
content::watch_for_reload, added alongside this).
English URLs throughout; review.yaml adds a qualifies-gated question
listing applicants via the generic NATS-KV resource mechanism, with
Invite/Decline transitions. Content pass: concrete/positive phrasing
(no negation constructions), warmer inclusive tone, light puns in the
encouragement lines.