Repository navigation
Give the buddy a map of the app: get_app_guide - #277
Conversation
The buddy could only answer "how do I create a project?" or "where do I set up roles?" from search_docs, which holds the project's material and has never heard of Sprintstart's own pages. - AppGuide: a hand-written catalog of the app's pages (route, where to find it, what it is for, how-tos in the UI's own labels, who may open it), mirroring the frontend's accessPolicy. - BuddyAppGuideTools: renders the guide for the caller only — filtered by their permission group and, for a PM, by the projects they manage — and lists what somebody else has to do (e.g. only an admin creates a project). Names the page the caller is on when the client sends it. - Mounted in both the hire's buddy and team mode. - SendBuddyMessageRequest.currentPage, threaded through to the tool. - UserApi.getPermissionGroup: the highest role, as the frontend sees it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The chip is gated on get_app_guide like every other chip on its tool. The dashboard's button is "Edit dashboard", and the onboarding page on dev has "Start step" / "Mark as complete" but no "Ask the buddy" yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…wledge # Conflicts: # src/main/kotlin/com/sprintstart/sprintstartbackend/onboarding/service/BuddyToolExecutor.kt # src/test/kotlin/com/sprintstart/sprintstartbackend/onboarding/service/BuddyToolExecutorTest.kt
dev turned the PM area into one page with a tab bar (Overview, Team with Members/Roles, Onboarding, Questions, Knowledge gaps, Escalations with Open/Durable answers). The guide now describes those tabs where they are, and its how-tos carry deep links that open the right tab (/team-management?tab=roles, /hire-setup?tab=arrival, /admin?tab=projects, /insights/knowledge-requests?view=answered) — only parameters the frontend reads, pinned by a test to stay on their own page. Also: Hire Setup's tabs are "Arrival"/"Starter work", the member page's role picker is "Choose role"/"Add role", "Rebuild path", and the onboarding page has "Ask your buddy about this". AGENTS.md says to keep AppGuide.kt in step with the frontend. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The frontend shows the manager pages only while a project the PM manages is selected, not whenever they manage one. Without saying so, the guide sent a PM looking at a project they only belong to to a sidebar entry that is not there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The frontend gained an admin-only Skills tab for the organisation-wide skill pool. HR is now told an admin does that, and an admin gets the deep link. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kiranfin
left a comment
There was a problem hiding this comment.
Review
The guide is carefully scoped: it is filtered by the caller's permission group and managed projects, currentPage is only matched against the catalog and never echoed, and the roles, tab parameters (tab, view) and quoted labels I cross-checked against the frontend's accessPolicy.ts and pages line up. I found no blockers. The open points are where the guide can still describe a different set of pages than the user actually has, and where the new currentPage plumbing is not pinned by tests.
🟡 Worth a look
1. Users who finished onboarding are still linked to /onboarding (AppGuide.kt:202-220, BuddyAppGuideTools.kt:603-606)
The page is registered with roles = EVERYONE, and Reader.opens only looks at the role and managerScoped. In the frontend, /onboarding is additionally gated by isOnboardingAccessible (!hasCompletedOnboarding) in AuthGuard and the sidebar, and the sidebar entry also needs an existing path. The guide lists the page under "Pages they can open (link each as Name)", so a finished hire, and in team mode nearly every manager, gets a link to a route that redirects. The "shown until their onboarding is finished" hint in whereToFind is not enough when the model is told to link every entry. Feed the completed flag into Reader and leave the page out (or list it as unavailable) for those users.
2. "Which projects does the PM manage" is derived from membership, with a query per project (BuddyAppGuideTools.kt:556-565)
managedProjectNames takes getUsersByIds(...).projects and runs canManageProject on each one (two queries per call). ProjectManagerService.setManager documents that manager access does not depend on the membership row. A manager whose assignment row is gone is therefore told "They manage no project yet" and loses every manager page in the guide while the backend still treats them as manager. Please ask for the managed projects directly (one UserApi/ProjectMembershipApi method keyed on the manager) instead of filtering the membership list.
3. The currentPage hand-off is only tested at the edges (BuddyService.kt:290,408, BuddyTeamService.kt:158-163, BuddyControllerTest.kt)
Tests cover controller → BuddyService.sendMessageForMe (hire path only), BuddyToolExecutor.execute and BuddyTeamTools.execute, but nothing pins the two middle hops: runToolCall → buddyToolExecutor.execute(call, userId, currentPage) and BuddyTeamService → TeamToolContext(currentPage = …). If either drops the value, every test stays green and "this page" silently stops working. There is also no controller test for teamProjectId + currentPage, and UserApiService.getPermissionGroup is untested (multi-role collapse e.g. PM+HR → HR, no roles → USER, unknown user → null).
🟢 Nits / cleanup
AppGuide.pageAtcompares exactly, so/team-management/(React Router accepts the trailing slash) is reported as "a page this guide does not describe".trimEnd('/')on the pathname before matching would fix it (BuddyAppGuideTools.kt:581-590).- A plain member gets every manager and admin how-to in the "Only somebody else can do these" block (about 15 lines on every call, with the manager's click path). Consider listing only the tasks a member could plausibly ask about, or collapsing it to one line per page, to save prompt space.
- For a PM without a managed project,
describeDoers(page.roles)yields "the project's manager, HR or an admin", which includes the asker's own role. The extra "manage no project" paragraph covers it, but the wording is confusing. - Question for the frontend PR: the chip "What can I do on this page?" resolves to the Buddy page itself when pressed on the full
/buddypage. Is the chip hidden there, or shouldBuddyhave its own how-to? - The description says this was not tried end to end with a real model. Since routing between
get_app_guideandsearch_docsrests only on the tool description, one manual run of "how do I create a project?" as PM, HR and admin before merge would be worth it.
Nothing here blocks the merge. Findings 1 and 2 are cheap to fix in this PR; finding 3 is the one I would not leave as a follow-up, because the currentPage plumbing is the new behaviour and has the least coverage.
…wledge
Keeps both sides of the buddy message request: dev's sessionId and filters,
and this branch's currentPage. The app guide follows dev's UI: the buddy page
now lists conversations ("Start a new conversation"), and adding a source
ends in "Connect now".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Short summary
Gives the buddy a map of the Sprintstart app itself, so "where do I create a role?" or "what can I do on this page?" is answered from the app instead of from
search_docs, which only knows the project's own material.get_app_guide, mounted in both the hire's buddy and team mode.AppGuide.kt: a hand-written catalog of every frontend page: where it is, what it is for, how to do things there (in the UI's own labels), who may open it, and per how-to a deep link to the right tab where the page keeps its tab in the URL (e.g./team-management?tab=roles). Includes the new admin-only "Skills" tab of Access Management.accessPolicy.ts). What the caller cannot do is listed as "ask X" instead of sending them to a page they can't open (e.g. creating a project is admin-only). A managing PM is told the manager pages only show while a managed project is selected.SendBuddyMessageRequest.currentPage(optional): the path the sender is on, so "this page" / "here" can be resolved. Only matched against the catalog, never echoed.UserApi.getPermissionGroup, and a "What can I do here?" suggestion chip.AGENTS.md: frontend page, tab or label changes must updateAppGuide.ktin the same piece of work.Checks
./gradlew check)AppGuideTest,BuddyAppGuideToolsTest, plus executor/team tools/controller/suggestion tests)Additional notes
Part of a three-repo change; each PR works on its own (the field is optional, the prompt clause only appears when the tool is mounted), but the feature needs all three:
Not yet tried end to end with a real model.
🤖 Generated with Claude Code