Commit Graph

37 Commits

Author SHA1 Message Date
e02a0c23d4 Make a conversation a registry, and add the second one
Some checks failed
CI / check (push) Failing after 4m57s
`positionFlow.js` was five per-domain concerns in one file — a field table, an
`@`-token resolver, a sentence extractor, a commit vocabulary and a set of
outcome renderers — and only the control flow between them was general.
Everything else knew it was creating a job posting. Adding a second
conversation meant a second copy of all of it.

So the control flow is now `conversationFlow.js` and each kind of record is a
REGISTRY. Which conversation a skill runs is the skill's own `flow:` line,
resolved through a map: `routing.js` used to say `if (skill.id ===
'create-position')`, which made a second conversational skill a change to the
router rather than a file on disk — the `if agent_key == ...` shape the
platform rules out one level up. The panel's write callback is likewise a map
keyed by flow id instead of an `onCreatePosition` prop, and the outcome wording
comes off the registry, so nothing in the panel names a kind of record any
more.

`create-employee-role` is the second registry. The worker is asked for and
never assumed: a conversation that names nobody re-asks rather than falling
back to the session, because an operator records this on somebody's behalf. Its
`extract` is deliberately narrower than the posting's — "bartender, weekends,
$30/hr" settles three fields and leaves the subject alone, since guessing WHO a
record is about from a fragment is how a role gets filed against the wrong
person.

THE CONFIRMATION STEP ACCEPTED "create position" AND SILENTLY REJECTED "create
positions" — the plural the Positions page itself uses. An anchored regex missed
it, and the reader got the summary back with no indication of what was wrong
with what they said, which is indistinguishable from the screen not having
updated. Matching is now exact membership against a normalized reply, so a
vocabulary is a list of phrases somebody can read rather than an expression
somebody has to parse.

Two bugs in `extractRole`, both of which fabricated a value nobody typed on the
one field a position cannot be created without:

  - The phrase pattern marks "new" as the role by the same grammar that marks
    "sous chef", so "create new position" opened the conversation titled "New".
    The scaffolding is a PHRASE at least as often as a single word, so a
    per-word test still produced "Brand New" and "One More". Scaffolding words
    are now stripped to DECIDE whether the phrase named anything, and the
    ORIGINAL phrase is returned when it did — strip to test, never to rewrite,
    or "second chef" becomes "Chef" and the cure is worse than the bug.

  - `(?:a|an)?\s*` has no word boundary, so it matched the leading "a" of
    "another" and the capture began mid-word. That mangled scaffolding into
    "Nother New" and, worse, corrupted every role introduced with "an":
    "create an open kitchen lead position" titled the position "N Open Kitchen
    Lead". A real role, typed correctly, silently wrong. Found by mutation
    testing the first fix.

`@companies` and `@workers` resolve from data the panel already holds — postings
and profiles the API has already scoped to the caller — so neither widens
anybody's view and neither costs a request. The company list is deliberately
unsorted: `useJobPostings` asks for `-created_date`, so the clients staffed for
most recently come first, and the panel does no ranking of its own. That last
part is a rule the suite enforces structurally, and it is the right rule — a
second opinion formed in the panel outranking the server's is exactly the kind
of thing that decays quietly.

`npm test` now refuses a conversation step whose field its registry does not
define. `stepsOf` drops unknown fields, so a typo means the flow asks fewer
questions than the file lists — and a skill whose steps are ALL unknown asks
none, jumps to the summary, and offers to write an empty record. Nothing errors
and the Markdown still reads correctly. 970 checks, up from 924; the new ones
walk both conversations end to end, because a wrong answer at the confirmation
step re-renders the same summary a right answer does.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJvibeSc1JYXjatankqM1g
2026-09-02 15:29:48 +05:30
1a0dc7e5f1 Settle subagents: it means delegate to, not borrow skills from
Some checks failed
CI / check (push) Has been cancelled
The key had two incompatible meanings running at once. CLAUDE.md §3 defines
subagents as "keys of other specs this may DELEGATE to" and §6 as a tool call
from the parent's perspective — the subagent runs its own turn, as the same
caller, out of the parent's budget, and returns an answer. The backend
implements exactly that.

This side did something else: agentSkillIds folded one level of subagent skills
into the parent's carried set, so a parent silently gained everything its
subagents carried, and the UI described it that way — "other agents whose
skills this one may also use", "borrowing them cannot reach data this page does
not hold".

Both are defensible readings. Only one is the specification, and running both
meant krow-workforce-agent carried eight delegation tools AND the flattened
skills of those same eight agents — able to answer a question directly or to
ask an agent that had already lent it the means to answer. Two ways to do one
thing, differing in cost and in what the trajectory records.

So an agent carries what it declares. Reaching another agent is delegation,
which the runtime does with its own budget and its own trajectory.

The blast radius was one check, which is the useful part of the answer: only
"a subagent cycle terminates" depended on the folding, because that traversal
was the only thing that could loop. Nothing walks subagents here now, so the
cycle question moved to where it belongs — refused at publish by
definition.FindSubagentCycle, bounded at run time by the depth cap. The
replacement checks assert the new meaning rather than deleting the old ones,
because the previous behaviour reads as perfectly reasonable and will be
reinvented otherwise.

The `agents` parameter stays on agentSkillIds and is no longer read. Removing
it is a wider edit for no behavioural gain, and agentScopedDisabledWith exists
precisely to pass it.

924/924 checks pass; production build clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJvibeSc1JYXjatankqM1g
2026-08-29 15:29:09 +05:30
1d35358dd6 Carry a routed question across the move, and let the Test tab actually test
TWO fixes, both found by using the product rather than reading it.

A question asked on a page that cannot answer it was lost. resolveIntent routes
to the page that can, and routing.js answered "That is on Candidates. Taking
you there now. Ask again once the page loads." — but the panel is page-scoped,
so it re-mounts on the new route and the navigation destroys the very message
explaining why the reader moved. What the reader saw was a different page and a
fresh greeting, with no trace of what they asked.

The question now travels with the destination. AssistantPanelContext sits ABOVE
the router and already has `ask` for exactly this — a page handing a question to
the panel — so the panel that mounts on the other side asks it. That is what
the reader wanted, and what "ask again once the page loads" was apologising for.
It cannot loop: resolveIntent only routes when the destination differs from the
page you are on, and answerableHere short-circuits before that.

The Test tab did not test. "Simulation & Scope Diagnostics" reads where a
question WOULD route — which skills are reachable, which tools are in scope,
what the classifier makes of it — and never calls the model. That is genuinely
useful and it is not what a tab called Test leads anyone to expect. A real test
did exist, but under Skills, as "Test in Owliver" on a capability card.

So the Simulated User Query the tab has always shown is now runnable, through
the same path that card uses: the existing Owliver panel, scoped to the draft's
own agent and disabled skills, so the answer comes from the agent being edited
rather than the published one. The diagnostics stay — they answer a different
and still useful question. The button is disabled when the agent does not cover
the selected page, with the reason in its title, rather than offering a run that
would decline.

924/924 checks pass and the production build is clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJvibeSc1JYXjatankqM1g
2026-08-29 15:13:53 +05:30
Suriyakumarvijayanayagam
140c608f8f Stop tracking .env; the ignore rules already exclude it
.gitignore excludes .env and .env.*, with !.env.example negating it for the
documented template. Those rules are correct — the comment above them records
a previous fix to a "#env" line that was commented out and so matched nothing.

But .env was committed while that typo was live, and an ignore rule does not
untrack a file that is already in the index. The result is that everyone's
local backend choice shows up as a modification to a committed file:

    M .env    VITE_API_PROXY_TARGET: production → 127.0.0.1:8080

Nothing secret is in there today; it holds URLs. The risk is the next value
that is not a URL, committed by someone who had no reason to think that file
was tracked. .env.example stays, so a fresh checkout still knows what to fill
in.

The file itself is untouched on disk.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJvibeSc1JYXjatankqM1g
2026-08-28 17:14:23 +05:30
4df7d75972 Add CI
Some checks failed
CI / check (push) Has been cancelled
The checks this repository already had, run on every push rather than when
somebody remembers: lint, skill-check, a production build, and the fixture
drift check against the backend.

Two of the steps guard against a suite that stops running rather than one
that fails:

  - npm test prints "N/M checks passed", and a suite that stopped reaching
    half its files still prints a pass line for the half that ran. The count
    now has a floor, so the number going down is itself a failure. Verified:
    a shrunken 120/120 fails, 900/924 fails, 924/924 passes.
  - the build asserts the API origin reached the bundle. VITE_* is inlined
    at build time with no runtime configuration, so a bundle built without
    it calls a relative /api/v1 that nginx serves as a static file — and a
    login POST answers 405 rather than failing anywhere visible.

The fixture job needs the sibling repository checked out. Where it is not,
it says so and fails rather than passing quietly: a check that cannot run
should not look like one that did.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0186JgqQUCDS8ZwGmyw3ymWu
2026-08-28 13:52:59 +05:30
88c412fda6 skill issue 2026-08-28 12:22:08 +05:30
814073e97b agnets done 2026-08-28 11:13:20 +05:30
eaf08e061d agnets done 2026-08-28 11:02:02 +05:30
ab9adde6cd update the chatbox 2026-08-25 18:56:07 +05:30
6c105f5b76 changes 2026-08-24 21:13:12 +05:30
0757bfb375 change base url 2026-08-24 21:00:39 +05:30
6d8b4dbf36 update owliver agent 2026-08-24 20:06:11 +05:30
02eb48af99 fix mobile screen issues 2026-08-24 13:16:15 +05:30
dcf9770ada chore: clean up and restructure repository 2026-08-21 11:11:21 +05:30
b2e6868824 update agents skill design 2026-08-20 18:18:10 +05:30
161b237695 update the workspace and skills flow 2026-08-20 11:04:13 +05:30
d3f7f439f6 update Markdown skills 2026-08-19 17:36:27 +05:30
aa2fb41871 workspace upadate 2026-08-17 19:52:44 +05:30
7fa21a4513 fix error line 2026-08-17 17:33:56 +05:30
69b38abced update draft issue 2026-08-15 23:24:06 +05:30
b349f2db61 fix pubilsh job posting 2026-08-14 18:01:43 +05:30
4fdfb90326 update owliver skill 2026-08-14 17:33:16 +05:30
cccada9bd2 position ui and owliver update 2026-08-14 01:18:59 +05:30
1c653264b5 update position page design 2026-08-13 21:41:14 +05:30
6340962907 remove create position button 2026-08-12 19:44:15 +05:30
3beb66059b update ui design for all pages 2026-08-12 18:56:56 +05:30
25c4ee4a6a update hired page 2026-08-11 19:17:40 +05:30
8a256a4de7 fix talent pool ui 2026-08-11 17:09:53 +05:30
7427359967 update ui changes 2026-08-10 19:51:49 +05:30
5cd49a1655 ui changes 2026-08-10 19:36:45 +05:30
409dffe938 fix port 2026-08-10 15:53:53 +05:30
312d2d9f4c fix mobile screen responsive 2026-08-10 14:47:19 +05:30
7b1af5a8ef add dockerfile 2026-08-10 14:37:51 +05:30
76412b08b4 fix Owliver ai chat 2026-08-10 13:19:10 +05:30
52fe6d9c14 promtbox update 2026-08-10 12:38:58 +05:30
0cae250049 update chatbox 2026-08-08 00:39:16 +05:30
90f14a73b2 Initial commit 2026-08-07 23:53:15 +05:30