110 lines
5.2 KiB
Markdown
110 lines
5.2 KiB
Markdown
# Rank
|
||
|
||
Interactive feature prioritization tool for `rank.friborg.uk`.
|
||
|
||
## Product definition
|
||
|
||
Rank is a fast intake and prioritization board for product ideas from Jimmi and agents.
|
||
|
||
Core loop:
|
||
|
||
`Capture idea → score impact/effort/confidence/urgency → drag into milestone → revisit top-ranked work`
|
||
|
||
Chosen subdomain: `rank.friborg.uk` — short, memorable, and honest about the job.
|
||
|
||
## UX principles
|
||
|
||
- One-screen capture, no modal ceremony.
|
||
- Keyboard-first: `/` focuses capture, Enter saves.
|
||
- Plain sharp visual system: zero rounded corners, dark space/glass, high contrast.
|
||
- Milestones are customizable lanes, not a rigid roadmap prison.
|
||
- Agents can post ideas through the same API endpoint as the UI.
|
||
|
||
## Architecture
|
||
|
||
- Node/Express app on port `3045`
|
||
- Static SPA in `public/`
|
||
- Appwrite TablesDB persistence
|
||
- Docker deploy on Unraid
|
||
- Gitea remote repo
|
||
- Nginx Proxy Manager routes `rank.friborg.uk` → `192.168.30.100:3045`
|
||
|
||
## Appwrite schema
|
||
|
||
Database: `priority_rank`
|
||
|
||
Tables:
|
||
|
||
- `ideas` — title, description, source, sourceName, milestoneId, impact, effort, confidence, urgency, score, rank, labels, notes, archived
|
||
- `milestones` — name, description, horizon, color, position, active
|
||
- `activity` — small append-only UX feed
|
||
|
||
## Scattermind → Ranker bridge
|
||
|
||
Ranker's continuation job is narrow:
|
||
|
||
`Snapshot / Concept Map → candidate feature/action set → Rank-ready build order`
|
||
|
||
`POST /api/rank-feedback` accepts a `prioritix-feature-set-v1`-style payload from Scattermind and returns ranked items plus `buildOrder.doFirst / validateNext / defer / park`. It accepts candidate arrays as `features`, `actions`, `nextMoves`, or `candidates` either at the top level or under `featureSet`, and it can consume a nested `conceptMap.nextActions / nextMoves` artifact directly, so Scattermind can hand off Concept Map next actions without renaming them into fake software features. It also returns a `brief` with source, next-48-hour actions, carried-forward assumptions/constraints/non-goals, and `whatWouldChangeRanking` checks, plus a `handoff` object (`rank-feedback-result-v1`) with source provenance, item trace rows, and contract warnings for missing artifact IDs, source sections, original prompt provenance, or evidence on active items. Keep this contract action-first; do not use it as a reason to add generic dashboard, auth, billing, or workspace layers before the bridge has proof.
|
||
|
||
Candidate items may include optional 1–10 `rankerHints` (`value`, `effort`, `confidence`, `urgency`, `revenue`, `novelty`, `risk`). Ranker blends those explicit Scattermind hints with text heuristics; `effort` is inverted into feasibility. Hints improve the defended order, but `recommendedLane: "defer"` or `"park"` remains a safety rail so dashboard-swamp items do not get promoted by flashy wording. For clean bridge handoff, Scattermind should send `sourceSection` and `evidenceNeeded` on each active next move. Scattermind can also send `targetAudience`, `constraints`, `assumptions`, and `nonGoals` / `avoid` at the top level, in `featureSet`, or inside `conceptMap.context`; Ranker returns that decision context in `input.decisionContext` and `handoff.decisionContext`, and penalizes candidates that conflict with source non-goals (for example saved workspaces/auth/billing before the continuation proof). If Scattermind sends duplicate candidate IDs, Ranker keeps the first ID, suffixes later duplicates (`preview-2`), and reports the normalization in `handoff.warnings` / `handoff.itemTrace` so downstream build-order references remain addressable.
|
||
|
||
Recommended payload shape:
|
||
|
||
```json
|
||
{
|
||
"schema": "prioritix-feature-set-v1",
|
||
"sourceName": "Scattermind",
|
||
"artifactId": "snapshot_or_concept_map_id",
|
||
"snapshotTitle": "Plain idea title",
|
||
"conceptMapId": "optional_concept_map_id",
|
||
"originalPrompt": "The user's starting prompt, trimmed for provenance",
|
||
"idea": "What Scattermind clarified",
|
||
"context": "Important constraints: solo builder, non-AI-native user, avoid dashboard swamp, etc.",
|
||
"mode": "mvp",
|
||
"featureSet": {
|
||
"features": [
|
||
{
|
||
"id": "build-order-preview",
|
||
"title": "Build order preview",
|
||
"description": "Show do first, validate next, defer, and park with reasons.",
|
||
"userValue": "A tired builder sees the next move without opening a dashboard.",
|
||
"evidenceNeeded": "Can 3 non-AI-native users understand the first recommended action?",
|
||
"proofSteps": ["Show a static result screen to 3 people"],
|
||
"rankerHints": {
|
||
"value": 8,
|
||
"effort": 3,
|
||
"confidence": 7,
|
||
"urgency": 6,
|
||
"revenue": 4,
|
||
"novelty": 5,
|
||
"risk": 3
|
||
},
|
||
"dependencies": [],
|
||
"risk": "May become generic roadmap UI if the source context is lost.",
|
||
"recommendedLane": "validate-next",
|
||
"sourceSection": "concept-map.nextMoves"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
## Commands
|
||
|
||
```bash
|
||
npm run setup:appwrite
|
||
npm run check
|
||
PORT=3045 node server.js
|
||
npm run smoke
|
||
```
|
||
|
||
Agent idea post:
|
||
|
||
```bash
|
||
curl -X POST https://rank.friborg.uk/api/ideas \
|
||
-H 'Content-Type: application/json' \
|
||
-H "Authorization: Bearer $RANK_AGENT_TOKEN" \
|
||
-d '{"title":"Add public roadmap export","source":"agent","sourceName":"Rook","impact":8,"effort":3,"confidence":7,"urgency":5}'
|
||
```
|