aravind changes

This commit is contained in:
2026-08-25 16:37:05 +05:30
parent cadea4bd92
commit b6f8655909
27 changed files with 5058 additions and 163 deletions

View File

@@ -1840,7 +1840,7 @@ Recorded in `docs/api-contract.md` §12 and still accurate against the current c
| **GCS-compatible object storage** | — | **Future direction.** No reference in the repository; `infrastructure/README.md` names MinIO as a "later" candidate | — |
| **Docker deployment** | — | **Future direction.** `infrastructure/` contains only a README; `Dockerfile.api` and `Dockerfile.owliver` are listed there as later work | — |
| **Redis** | Shared state for rate limiting across instances | **Future direction.** `ratelimit.go` names Redis or the database as the seam; nothing is wired | Needed before multi-instance deployment for the limiter to mean anything |
| **NATS is not part of the target architecture** | — | **Future direction / stated rule.** Note the discrepancy: `infrastructure/README.md` currently lists NATS as a later docker-compose candidate. See §17. | Remove NATS from that table if the rule stands |
| **NATS is not part of the target architecture** | — | **Future direction / stated rule.** `infrastructure/README.md` previously listed NATS as a later docker-compose candidate; that table has been corrected. See §17.17. | Keep it out |
| **RAG / pgvector** | — | **Future direction.** `pgvector` is not installed in the local database and is named only once, in `infrastructure/README.md` | Introduce when the architecture calls for it |
---
@@ -1850,35 +1850,31 @@ Recorded in `docs/api-contract.md` §12 and still accurate against the current c
Everything below was checked against the current repository. Items the request asked
about that could not be verified are marked as such rather than guessed at.
### 17.1 Documentation is behind the code
### 17.1 Documentation is behind the code — resolved
**Issue.** `README.md` describes the repository as being at an earlier stage than the
code is. It states "Authorization — which roles may do what — is Phase 3D and is not
implemented", "Authorization is **not** implemented. `users.role` is carried on the
identity and consulted nowhere: any signed-in user reaches every endpoint", "38
endpoints" and "55 tests".
**Issue as recorded.** `README.md` described the repository as being at an earlier
stage than the code is. It stated "Authorization — which roles may do what — is Phase
3D and is not implemented", "Authorization is **not** implemented. `users.role` is
carried on the identity and consulted nowhere: any signed-in user reaches every
endpoint", "38 endpoints" and "55 tests". The same staleness appeared in two source
comments: the `internal/httpserver/server.go` package documentation ("Authorization is
NOT here"), and `internal/authctx/authctx.go` ("It is NOT consulted anywhere in Phase
3C: authentication only").
**Cause.** Authorization, the definition tables, the CRUD surface and the runtime all
landed after the README was last revised.
**Impact.** A reader trusting the README would conclude that any signed-in user
reaches every endpoint, which is not what the code does.
**Current behaviour.** `internal/domain/policy.go`, `Server.authorize`,
`builder.ownership` and `internal/httpserver/rbac_test.go` (730 lines) all exist and
run. 51 routes are registered. 175 test functions run.
`docs/api-contract.md` §9A *is* current and documents the authorization contract
accurately.
run. 51 routes are registered. 175 test functions run. `docs/api-contract.md` §9A
*is* current and documents the authorization contract accurately.
**Possible future handling.** Revise `README.md` against the code.
The same staleness appears in two source comments:
- `internal/httpserver/server.go` package documentation: "Authorization is NOT here.
A signed-in user reaches every endpoint they could reach before".
- `internal/authctx/authctx.go`: "It is NOT consulted anywhere in Phase 3C:
authentication only" — `Identity.Role` is now consulted by `Server.authorize`,
`builder.ownership`, `guardInsert` and `service/definitions.go`.
**Resolution.** `README.md` was revised against the code: the status paragraph, the
layout tree (which was missing `cmd/setpassword`, `internal/auth`, `internal/authctx`,
`internal/definition` and `internal/runtime`), the route count, the test count and the
authorization section. The `server.go` and `authctx.go` package comments were
corrected to describe the authorization that exists. `internal/orgctx/orgctx.go`,
which still framed itself as pre-authentication, was corrected in the same pass.
### 17.2 The definitions endpoints are not in the API contract
@@ -2000,23 +1996,26 @@ the effective limit multiplies by instance count, resets on restart, and degrade
a global budget behind a reverse proxy. **Possible future handling:** move the
limiter behind shared state before deploying more than one instance.
### 17.10 The repository has no commits
### 17.10 The repository has almost no history
**Issue.** `git log` reports `fatal: your current branch 'main' does not have any
commits yet`. Every file is untracked.
**Issue as recorded.** `git log` reported `fatal: your current branch 'main' does not
have any commits yet`, and every file was untracked.
**Impact.** There is no history, no recovery point, no blame, and no record of when
any of the work described in §2 happened. The chronology in this document was
reconstructed from migration headers, package documentation and the contract, not
from version control.
**Current behaviour.** The tree is now committed: a single commit on `main`
(`7d12ebe`, "first commit") holds the whole repository.
**Note.** This document does not change that; no commit was made.
**Remaining impact.** One commit is not history. There is still no blame, no
incremental recovery point, and no record of when any of the work described in §2
happened. The chronology in this document was reconstructed from migration headers,
package documentation and the contract, not from version control, and that remains
the only source for it.
### 17.11 A minor documentation defect in the source
### 17.11 A minor documentation defect in the source — resolved
`internal/httpserver/api.go` — the doc comment describing `decodeBody` sits
immediately above `decodeInto`, so `decodeInto` carries two doc comments and
`decodeBody` carries none.
`internal/httpserver/api.go` — the doc comment describing `decodeBody` sat
immediately above `decodeInto`, so `decodeInto` carried two doc comments and
`decodeBody` carried none. The `decodeBody` comment has been moved to sit above
`decodeBody`.
### 17.12 Badge endpoint mismatch — verified
@@ -2091,8 +2090,9 @@ among the things that do not exist yet.
**Impact.** A reader of `infrastructure/README.md` would take NATS to be planned.
**Possible future handling.** Amend that table if the rule stands. Nothing was changed
here.
**Resolution.** The rule stands, so the table was amended: `infrastructure/README.md`
no longer lists NATS as a candidate and says explicitly that it is not part of the
target architecture. `README.md` no longer names it either.
### 17.18 Deliberate contract behaviours that read as defects
@@ -2169,8 +2169,8 @@ deliberately and should be done knowingly.
### NATS
**NATS is not part of the target architecture.** Note that `infrastructure/README.md`
currently lists it as a later candidate; see §17.17.
**NATS is not part of the target architecture.** `infrastructure/README.md` no longer
lists it as a candidate; see §17.17.
### Nearest-term work implied by the code itself
@@ -2281,9 +2281,9 @@ disposable `krow_backend_autotest_<pid>` database per test process.
**Current Known Limitations:** no AI execution and no public runtime endpoint; login
rate limiting is per-process and in-memory; CORS does not permit credentials;
definitions endpoints bypass the policy table; the runtime package is unreachable
from the running service; `README.md` and two source comments are behind the code;
the definitions endpoints are absent from the API contract; attendance data is empty
without a rostering source; the repository has no commits.
from the running service; the definitions endpoints are absent from the API contract;
attendance data is empty without a rostering source; the repository has a single
commit and so no usable history.
**Current Development Focus:** the most recent work in the tree is the definition
system — schema, parser conformance, CRUD — and the runtime boundary that sits on top
@@ -2392,13 +2392,12 @@ is how this codebase would stop being trustworthy.
- **The main current limitations** are: no AI execution and no runtime endpoint;
login rate limiting that does not survive scale-out; CORS that does not yet permit
credentials; ten definition endpoints that sit outside the policy table and outside
the written contract; documentation that is behind the code; and a repository with
no commits.
the written contract; and a repository with a single commit and so no usable
history.
- **The direction** is real execution behind the existing executor interfaces
(Owliver / an LLM provider abstraction), then retrieval, then tooling, then
deployment infrastructure — none of which exists here today. **NATS is not part of
the target architecture**, and the one place in the repository that still names it
should be corrected.
the target architecture**, and the documentation no longer implies otherwise.
- **The rules that must not be broken** are in §21. The two that matter most in daily
work: never trust a client-supplied identity or tenant, and never rewrite stored
Markdown.
@@ -2409,3 +2408,9 @@ is how this codebase would stop being trustworthy.
behaviour above was read from the current checkout or from read-only queries against
the local development database. Nothing in the repository was modified to produce
this document.*
*Revised on 2026-08-24 by a structure-and-dead-code cleanup pass, which changed no
schema, no migration, no database row and no runtime behaviour. What it did change is
recorded in §17.1, §17.10, §17.11 and §17.17: documentation and source comments that
had fallen behind the code were corrected. The counts above were re-verified against
the checkout and are unchanged.*

View File

@@ -129,6 +129,125 @@ these would leave the shim with methods that 404. See §11 (D6).
---
## 2A. Owliver suggestions
`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`.
It is not on the public allowlist. Which readings exist depends on the caller's
role, so there is no anonymous answer to give.
### Request
| Parameter | Required | Meaning |
| --- | --- | --- |
| `page` | yes | A surface id from the closed page vocabulary — the same one `internal/definition` validates a definition's `pages:` against. Aliases (`hired`, `forge`, `new-position`) and loose spellings (`Talent Pool`) resolve to the canonical id. |
| `query` | no | What the user has typed so far. |
Any other parameter is `invalid_query`. **Nothing about the caller is accepted
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.
### Response
```json
{
"data": {
"suggestions": [
{ "text": "Which position has the strongest pipeline?", "intent": "position-strength" },
{ "text": "Show hiring activity as a flow", "intent": "hiring-operations", "capability": "flow" }
]
}
}
```
`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.
| Field | Meaning |
| --- | --- |
| `text` | The question, as the user reads it. |
| `intent` | The **frontend capability id** the panel dispatches on, verbatim from the manifests in `src/components/ai-assistant/capabilities/`. Not a backend identifier, and never invented here. |
| `capability` | The section type to draw the answer as, from the closed `OWLIVER_CAPABILITIES` vocabulary. Present only when the query asked for one ("as a flow", "summarize"); absent otherwise. |
Nothing internal is exposed: no matching terms, no resource names, no scores, no
policy detail. `text` is always catalogue wording — no part of the query is
echoed back into a suggestion.
### Selection
Five stages, each of which only ever removes:
```
the page's catalogue → permission → relevance → deduplicate → top 3
```
- **Page.** Intents are keyed by surface, so a suggestion from another page
cannot appear. The same word answers differently per page by construction:
`pipeline` on `positions` is about which role converts, on `candidates` it is
the funnel the applicants are in.
- **Permission.** Each intent declares the resources it reads, and those are
checked against the policy table in §9A — *before* ranking, so a refused
reading is never scored. Two gates, not one: the role must be allowed the
operation, and for an organization-wide reading the role's rows must not be
narrowed. Talent may list job applications; talent may not be offered "which
position has the strongest pipeline?", because their view of that resource is
their own rows. No role list is written down here — see §9A.1.
- **Relevance.** Deterministic keyword ranking over the intent's own terms.
Exact token, then multi-word phrase, then prefix (so a half-typed word still
matches), then extension. Ties break on catalogue order, so the same request
always answers identically. A query naming only a section type ranks the
page's readings; once it names a subject, readings that merely *support* that
shape are dropped rather than used as padding.
- **Deduplicate.** One suggestion per intent id, and no two with the same text.
- **Cap.** Three. Nothing is added to reach three.
A query with fewer than two letters or digits after normalization returns `[]`.
### Normalization
The query is truncated to 200 characters, lower-cased, and reduced to letters,
digits and single spaces — every other character becomes a space rather than
being stripped, so nothing can be glued into a token that was not typed as one.
There is no injection surface to defend: the normalized text is compared against
a fixed table of literals and never reaches SQL, a template, a shell or a log
message. Hostile input is ranked like any other text, and can only ever produce
entries the catalogue already holds.
### Where the catalogue comes from
The frontend owns the vocabulary. Owliver's capabilities are declared per page
context in `src/components/ai-assistant/capabilities/`; `internal/owliver`
transcribes the id and the page, and adds the two things a manifest does not
carry — the words that mean a user is reaching for that reading, and the records
it reads. Same pattern as `internal/definition/vocabulary.go`, and for the same
reason: one vocabulary, named from both ends, with a test on this side that
fails when an id here names no capability there.
**No table, no migration.** The suggestions are derived from definitions that
already exist. Persistence would only be warranted if suggestions became
admin-managed, and nothing in the product asks for that today.
### Not covered
The seven workspace and configuration surfaces — `settings`, `workspace`,
`workspace-agents`, `workspace-skills`, `workspace-skill-configure`,
`skill-development`, `workspace-agent-configure` — are valid pages with no
entries. Their panel answers from the registries rather than from workforce
records, so there is nothing to rank a typed query against. They return `[]`,
which is the honest answer, not a validation error.
---
## 3. Request schemas
### 3.1 Create — `POST /{resource}`

File diff suppressed because it is too large Load Diff