66 lines
3.2 KiB
Markdown
66 lines
3.2 KiB
Markdown
# Owliver behaviour baseline
|
|
|
|
`owliver-baseline.json` records how the panel routed and answered before the
|
|
agent layer existed. `skill-check.mjs` asserts against it on every run.
|
|
|
|
Regenerating it is a deliberate act, and the reason belongs here.
|
|
|
|
## 2026-08-27 — the seed gained the three statuses nothing exercised
|
|
|
|
`application_status` has seven values. The fixture produced four: `applied`,
|
|
`ai_screened`, `interview`, `hired`. `shortlisted`, `rejected` and `assigned`
|
|
existed only in the schema, and `Assignment` shipped empty by design.
|
|
|
|
That gap was hiding real defects, all found the same week and none visible
|
|
against the old data:
|
|
|
|
- `atOrBeyond` ranks a status by its index in `STAGE_ORDER`, which listed five
|
|
of the seven. `rejected` and `assigned` scored -1 and dropped out of *every*
|
|
bucket including `applied`, so a position's funnel lost people and a role
|
|
whose candidates had all been assigned read as unfilled.
|
|
- The agent's `candidates_awaiting` excluded `hired` and `rejected` from "still
|
|
in the running", so somebody already working a shift was offered as a person
|
|
to chase.
|
|
- `insights.stalled` counted "screened and waiting on a decision" as
|
|
`status === 'ai_screened'` only, silently dropping the shortlisted — the
|
|
people that phrase most describes. Caught by this regeneration, not before it.
|
|
|
|
**The change:** three existing applications were converted, not added, so every
|
|
regression anchor holds — 24 applications, 9 scored averaging 76, 3 staff,
|
|
8 postings, all unchanged.
|
|
|
|
app_kevin applied → rejected (never scored; a hard requirement)
|
|
app_sofia ai_screened → shortlisted (the strongest screened candidate)
|
|
app_marco hired → assigned (hired, then rostered)
|
|
|
|
Plus one `Assignment` for Marco — the minimum that makes `assigned` real. Eight
|
|
of the nine positions still have none, so every reader still meets the empty
|
|
case.
|
|
|
|
**What drifted, verified before regenerating:** one number, in four prompts.
|
|
Kevin left `applied`, so the unscored count reads 9 where it read 10:
|
|
|
|
"Show the 10 applications waiting for review" → "…9 applications…"
|
|
"10 have no score" / "10 unscored applicants" / "10 unscored applications"
|
|
|
|
Nothing else moved. `1 waiting on a decision` briefly became a fallback prompt
|
|
and that was the `stalled` defect above — fixed in `insights.js` rather than
|
|
absorbed into the baseline, and the prompt came back on its own.
|
|
|
|
## 2026-08-27 — the local simulator was removed
|
|
|
|
The panel used to answer from two places: an agent, and ~3,300 lines of
|
|
browser-side templates. Two paths behind one avatar meant the same question got
|
|
different answers depending on phrasing, so the templates were deleted.
|
|
|
|
**What actually drifted, verified before regenerating:** one thing. The
|
|
"I do not have that on this page" decline used to list the page's capability
|
|
labels as bullets — those labels were the simulator's canned readings and went
|
|
with it. It now names the page's topics in a sentence.
|
|
|
|
doc shape: ["text","list","note"] → ["text","text","note"]
|
|
|
|
Every intent `kind` was unchanged. No routing moved, no skill matching changed.
|
|
That is why this regeneration was safe: the diff was read first, and it was one
|
|
cosmetic change on a path that only runs when no agent is configured at all.
|