agent build

This commit is contained in:
2026-08-28 12:21:44 +05:30
parent b6f8655909
commit f7df96c973
138 changed files with 24164 additions and 207 deletions

View File

@@ -134,9 +134,33 @@ these would leave the shim with methods that 404. See §11 (D6).
`GET /api/v1/owliver/suggestions?page={surface}&query={typed}`
The one endpoint here that serves no resource. It answers "what could I usefully
ask on this page?" for the Owliver panel, which calls it while the user types —
so it reads no table, opens no transaction, calls no model, and its whole answer
is computed from a static catalogue in `internal/owliver`.
ask on this page?" for the Owliver panel, and it answers two different questions
depending on whether anything has been typed:
- **`query` present** — ranked against the static catalogue in `internal/owliver`.
No table is read, no transaction is opened and no model is called: the panel
issues one of these per keystroke, so the whole answer is a few string
comparisons.
- **`query` absent** — ranked against **the organization's actual state**, read
from PostgreSQL in one statement: how many positions are unfinished drafts,
how many active roles nobody has applied to, how many candidates are waiting
on a score, how many interviews carry a flag. This is one query per opened
panel, and it is what makes a suggestion react to the data — creating a
position changes what comes back next time it is asked.
Ranking here is by **tier first, count second**. Each reading declares how
much its subject matters when it is happening at all — a role nobody has
applied to outranks a queue of unscored candidates, which outranks a
headcount — and the count only orders readings inside a tier. Weight × count
would mean the largest pile always won, so a workspace with forty
applications and one abandoned role would be asked about the forty. A count
of zero scores nothing whatever its tier, so a page with nothing to report is
offered nothing rather than an urgent-sounding question about an empty set.
Only counts are read. Nothing that could name a record, a person or an id
reaches the ranking, and a talent caller's counts are never read at all: every
figure behind a highlight is organization-wide, and their rows are narrowed by
the policy table.
It is not on the public allowlist. Which readings exist depends on the caller's
role, so there is no anonymous answer to give.
@@ -153,8 +177,11 @@ here** — role, organization and user are read from the session, and a request
that names one is refused rather than ignored.
An unknown `page` is `invalid_query`, with the frontend's own wording:
`Unsupported page: {value}. Supported pages: {…}.` An absent, blank or
too-short `query` is **not** an error — there is simply nothing to rank yet.
`Unsupported page: {value}. Supported pages: {…}.` An absent or blank `query` is
**not** an error — it is a request for what the data itself suggests. A `query`
that was typed but is too short to rank (under two letters or digits) answers
with `[]` rather than falling back to the data: the user is mid-word, and
replacing what they are typing towards would flicker.
### Response
@@ -170,7 +197,18 @@ too-short `query` is **not** an error — there is simply nothing to rank yet.
```
`data.suggestions` is always an array — `[]` when nothing matches, never `null`
and never an error. There is no `meta`: the list is capped rather than paged.
and never an error. At most **three**, always. There is no `meta`: the list is
capped rather than paged.
`capability` names the section type the answer should be drawn as, and is
present only where the query asked for one — so a highlight, which nobody typed,
never carries it. `intent` is the frontend capability id the panel dispatches
on; it is not invented server-side, and
`TestIntentIDsAreFrontendCapabilities` holds the two vocabularies together.
An empty array with no query typed means the organization has nothing worth
raising — a workspace with no positions is asked nothing rather than asked three
questions about empty sets.
| Field | Meaning |
| --- | --- |