How team records work
The team records hold tasks, the backlog, tickets, learning, daily hours and XP.
They are plain files in nepwalk-docs, so they travel with your normal docs pull
request: when it is merged, everyone has them. There is no server, database or
separate sharing step.
The model in one minute
- Every record is one small JSON file under
docs/team/records/, for exampletasks/header-footer.jsonorsessions/umang/2026-10-25.json. Members and team settings live inteam.json. - Because each record has its own file, pull requests from different people merge one by one without conflicts. Only two changes to the same record (the same task, say) can conflict, and Git names that one file.
- Every change is an operation: who did what, when, with which details.
docs/team/core.jschecks it against the team rules before anything is written. An invalid change writes nothing. - Write records only through the dashboard or
node tools/team.mjs; never edit the files by hand.docs/team/snapshot.jsis a local copy for the dashboard. It is not committed; the docs build makes its own.
Daily dashboard opening
The first today request opens the dashboard in your default browser. Completed
AI onboarding runs open --once and shares that daily guard: onboarding followed
by today opens only one tab. Repeated requests, including a new AI session, do
not reopen it that day. Explicit open still works whenever you want it.
The marker is .team-local/dashboard-open.json, ignored by Git and separate from
your fixed identity. Days follow Kathmandu time. Each clone has its own marker.
The snapshot refreshes on each today; refresh an already-open browser tab to see
new records. today --member ... and today --date ... are read-only inspection
commands and do not open the browser. NEPWALK_TEAM_NO_BROWSER=1 disables launching
for headless use and does not mark the day as opened. A failed browser launch also
leaves the day unmarked, prints the dashboard path and keeps your tasks available.
Your docs branch
Each person keeps one branch in nepwalk-docs: team/<your id>, for example
team/umang.
# Once
git fetch origin
git switch -c team/umang origin/main
# Each morning: bring in everything merged since yesterday
git pull origin main
# At the end of the day: commit the records, push, open or update the pull request
git add docs/team
git commit -m "chore(team): umang 2026-10-25"
git push -u origin team/umang
Docs work for a task can go on the same branch. The founder merges the pull requests one by one, together with the frontend and backend ones.
Commands
| Command | What it does |
|---|---|
onboard --member <id> |
Claims this workspace once; an existing claim cannot be changed |
doctor |
Checks Node, Git, access, team files and sibling repos |
open |
Opens the dashboard whenever you explicitly request it |
open --once |
Opens it once per Kathmandu day; used when onboarding finishes |
today |
The short daily view; automatically opens the dashboard once per day |
standup |
Today's standup report, ready to paste into Slack (founder and manager) |
team |
Everyone's progress, waiting work, blockers and tickets (founder and manager) |
warriors |
The warriors' trek: everyone's rank, badges, weekly goal and victories |
brief <task-id> |
One task in full, with its history and stage |
backlog |
Backlog tasks open to your role, and whether you can pick now |
progress |
Your camp, XP, badges, week and streak |
learning [--member <id>] |
Learning roadmaps with summaries |
record <type> '<json>' |
Records one operation as you |
clip <file.png> |
Saves the image in your clipboard as a PNG file |
closure --work <h> --learning <h> --note "..." |
Closes the day (--day for an earlier day this week) |
prepare <list.json> --output <update.json> |
Builds a checked update file from a list of operations |
apply <update.json> |
Records every operation in an update file, once |
snapshot [--output <file>] |
Writes the dashboard's records snapshot |
validate |
Checks every record file and attachment |
Run them from the nepwalk-docs root. --member <id> chooses the initial
onboarding identity or a read-only view. record, prepare, apply and closure
always use the saved profile and reject mutation overrides. Imported operations
must all belong to that identity. --date YYYY-MM-DD views another day.
Recording one change
node tools/team.mjs record task.start '{"id":"header-footer"}'
The command adds the operation id, your identity and the time. It prints any XP, camp or badge earned, and the next step.
Task stages
stateDiagram-v2
[*] --> backlog: created without assignee
[*] --> ready: created with assignee
backlog --> in_progress: claim
ready --> in_progress: start
in_progress --> testing: checks passed or not applicable
testing --> review: manual test passed
testing --> in_progress: manual test failed
review --> reviewed: review approved
review --> in_progress: changes requested
review --> accepted: founder accepts (founder is the reviewer)
reviewed --> accepted: founder accepts
accepted --> released: release recorded
accepted --> in_progress: reopen
A member who picked a backlog task can return it while it is in progress. The
founder can pause, cancel, reassign or unblock tasks; a paused task starts again
only after the founder resumes it with task.assign. One active task per person
counts in progress, testing, review, reviewed and blocked.
Operations
"Founder" means the operation is refused for anyone else. Fields with ? are
optional. Ids use lowercase letters, numbers and hyphens.
Team
| Type | Who | Payload |
|---|---|---|
member.add |
Founder | id, name, role (engineer or manager), skills?, availability? |
member.update |
Founder | id, active?, name?, skills?, availability? |
policy.update |
Founder | weekStartsOn? (0 = Sunday), weeklyHours? {work, learning}, xp? {review, learning, application, ticket} |
rest.add |
Founder | memberId (empty for everyone), week (any day in it), note |
rest.remove |
Founder | id, for example *:2026-11-08 or umang:2026-11-08 |
Plans and designs
| Type | Who | Payload |
|---|---|---|
milestone.create, milestone.update |
Founder | id, title, outcome, target? |
milestone.accept |
Founder | id, note; every task of its features must be accepted |
feature.create, feature.update |
Founder | id, title, problem, outcome, scope, acceptance (list), milestoneId?, card?, requiresPrototype? (default true), prototype? |
feature.approve |
Founder | id, phoneConfirmed: true when a prototype is required |
Updating a feature sends it back to draft; tasks for it cannot start until it is approved again.
Tasks
| Type | Who | Payload |
|---|---|---|
task.create |
Founder | id, title, brief, acceptance (list), assignee (empty = backlog), reviewer? (default founder, never the assignee), priority (P0-P3), kind (implementation, test, research, documentation), points? (0-100, default 10), openTo? (anyone, engineer, manager), scheduledFor?, optional?, dependencies?, featureId?, ticketId? |
task.assign |
Founder | id, assignee (empty = backlog), reviewer?, scheduledFor?, note |
task.claim |
A member with nothing assigned that can start | id |
task.return |
The member who picked it | id, note |
task.start |
Assignee | id |
task.check |
Assignee | id, result (passed, failed, not_applicable), note |
task.manual |
Assignee, reviewer or founder | id, result (passed, failed), note, humanConfirmed: true |
task.review |
Reviewer (not the assignee) | id, result (approved, changes_requested), note |
task.accept |
Founder | id, note |
task.reopen, task.release, task.pause, task.cancel |
Founder | id, note |
task.note |
Assignee, reviewer or founder | id, note |
task.block |
Assignee | id, note |
Example: the founder adds a backlog task for engineers.
{
"type": "task.create",
"payload": {
"id": "tidy-footer-links",
"title": "Tidy footer links",
"brief": "Remove dead links from the footer. Check every link on phone and desktop.",
"acceptance": ["No footer link returns 404", "Links open in the same tab"],
"assignee": "",
"reviewer": "prakash",
"priority": "P2",
"kind": "implementation",
"points": 5,
"openTo": "engineer"
}
}
Tickets
| Type | Who | Payload |
|---|---|---|
ticket.create |
Anyone | id, kind (bug, feature), title, description, steps?, expected?, actual?, attachments? |
ticket.comment |
Anyone | id, note, attachments? |
ticket.triage |
Founder | id, status (backlog, duplicate, rejected), note |
Learning and days
| Type | Who | Payload |
|---|---|---|
learning.create |
Anyone for themselves; founder for everyone (audience: "all") or chosen members |
id, title, category (ai, technical, management, business, other), goal, path?, resource? |
learning.start |
The learner | id |
learning.review |
The learner | id, teachBack, questions (list of {question, answer}), gaps?, summary, understood |
learning.apply |
The learner, after understanding | id, note |
session.close |
Anyone, for themselves | day, workHours?, learningHours? (quarter hours, 0-16), note? |
Use the closure command rather than session.close directly. Closing the same
day again replaces the hours you give and keeps the others. Days can be closed
up to 7 days back, never in the future.
Several changes at once
Write a list and turn it into an update file:
[
{ "type": "milestone.create", "payload": { "id": "polish", "title": "Trip page polish", "outcome": "Leaders can read the trip on a phone without zooming" } },
{ "type": "ticket.triage", "payload": { "id": "footer-overlap", "status": "backlog", "note": "Valid" } }
]
node tools/team.mjs prepare plan.json --output update.json
node tools/team.mjs apply update.json
prepare checks every operation against the current records and writes the update
file without recording anything:
{
"schemaVersion": 2,
"projectId": "nepwalk-team",
"operations": [
{ "id": "op-91a2...", "type": "milestone.create", "actor": "prakash", "at": "2026-10-25T03:15:00.000Z", "payload": { "id": "polish", "title": "Trip page polish", "outcome": "..." } }
],
"attachments": []
}
apply records all operations or none, then renames the file to
update.json.applied so it is not applied twice.
Screenshots and prototypes
- In a payload,
{"file": "path/to/shot.png"}attaches a local file and{"clipboard": true}attaches the image you copied (it useswl-pasteorxclipon Linux,pngpasteor AppleScript on macOS, PowerShell on Windows). The dashboard does the same through its file fields. - Files are stored as
docs/team/assets/<sha256>.<ext>. The name is the content hash, so a file can never change silently. - Tickets accept PNG, JPEG and WebP screenshots. Features also accept one HTML prototype. Up to 5 MiB per file, 10 files and 20 MiB per update. File types are checked by their content, not their name.
- Git keeps every attachment forever. Crop screenshots and keep them small.
- HTML prototypes open in a sandbox inside the dashboard. Attach only self-contained prototypes with no outside requests.
The dashboard
node tools/team.mjs openopensdocs/team/dashboard.htmlin your browser. The docs site has it too, under Team.- Connected (Chrome or Edge): click "Connect nepwalk-docs folder" and choose
your
nepwalk-docsfolder once. Every change is checked and saved straight intodocs/team/records, exactly like the command line. The browser remembers the folder; on a later visit one click reconnects it. - View only (other browsers, or without connecting): you see everything. When
you make a change, the page checks it and shows the
node tools/team.mjs recordcommand that saves it. Run it innepwalk-docs, or give it to your AI tool. - Either way, nothing is shared until you commit the records on your branch and the pull request is merged.
When something goes wrong
| Message | What to do |
|---|---|
| Choose your identity first | node tools/team.mjs onboard --member <id> |
... does not match the record inside it |
A record file was moved or renamed by hand. Put it back with git checkout -- docs/team/records, or ask for help. |
... is not a team record |
A stray file sits in docs/team/records. Remove it. |
A pull request conflicts in docs/team/records/... |
Two people changed the same record. Merge main into your branch and keep both changes by recording them again, or ask the founder. |
| Another team write is active | Wait. If a write was interrupted, check no command is running, then delete .team-local/write.lock. |
| The dashboard says the records are not loaded | Run node tools/team.mjs open, or connect the folder. |
node tools/team.mjs validate checks every record file and attachment.
Privacy
Everything in the records is visible to the whole team, and the docs site is behind Cloudflare Access. Business plans, money, customer data and passwords still stay out of records, screenshots and prompts, as for the rest of this repository.
Fixed local identity
Choose your real name once with onboard --member <id>. The claim lives in the
ignored .team-local/profile.json. Repeating onboarding for the same member is
safe; choosing someone else is refused. Existing valid profiles are retained.
A malformed or inactive profile must be resolved, never silently replaced.
The browser confirms a first claim and remembers it in local storage. Connecting the docs folder adopts its existing profile or saves the browser's claim there. If the two disagree, connection is refused. Browser saves recheck the file before writing. The account label is fixed; opening another member's tasks never changes who acts. Own task controls, explicitly assigned reviews, and founder decisions follow the existing role rules. Unrelated tasks show a view-only label.
Without folder access, the browser remembers only that browser/origin's claim. Use the same local URL or connect the folder so it can reconcile with the CLI. Clearing browser data or opening a different origin can ask for onboarding again. No GitHub username mapping, login service or PR-author enforcement is installed. This is an accidental-switching guard. A person with local file/code access can change it. Private repository access does not authenticate a selected name.
Recover an incorrect first selection
There is no switch-account button or reset command. Ask Prakash to confirm the correct person first. Close AI writers and dashboard tabs. Preserve any existing work; identity recovery must not alter task or learning records.
- Back up
.team-local/profile.jsonlocally, then remove only that profile file. - For the relevant browser origin, remove only the local-storage key
nepwalk-team-identity-v1using browser developer tools. - Reload and onboard once as the confirmed member, then reconnect the docs folder.
- Check the fixed name before recording anything. Never use recovery to do someone else's assigned work or to rewrite past attribution.
AI must not perform this recovery automatically after a permission error. Obtain an explicit correction request and preserve records. The procedure is deliberate friction, not a secure administrator-only reset.
Viewing a teammate’s full profile
The founder and manager can open Everything about Niwesh (or another teammate)
from Warriors or team learning. It opens a full page such as
dashboard.html#member=niwesh; it is not a profile popup. Warriors combines delivery oversight with every active teammate’s level, XP, badges and learning progress. Detailed hours and task boards are expandable. The founder has no separate growth tab; old growth links open Warriors.
A member profile includes current level and XP, earned badges and unlock progress, current and past assigned tasks, pending reviews, learning summaries and teach-back history, reported tickets and contributed evidence, and daily handoffs.
Tasks by date separates planned task dates from actual task-history events. Each event names the person who performed it and uses Kathmandu time. A scheduled task is labelled as planned; its current status is not presented as its historical status. Closures supply logged hours. A date with no closure or activity does not prove that the person did no work. Learning application notes remain in the topic record; the profile does not invent a date when one was not separately recorded.
Filter a date to get a bookmarkable URL, for example
dashboard.html#member=niwesh&day=2026-10-22§ion=member-activity. All dates returns to the
complete recorded history. Refresh preserves the profile and date; Back to team
returns to the team view.
Viewing another person never changes the fixed local identity. A founder remains the founder. Task controls keep their existing role permissions; opening a profile does not permit working as the teammate. Engineers can view their own full profile; full profiles of others, including hours, are reserved for the founder and manager. Inactive teammates’ recorded history remains available by profile URL. Founder personal development remains outside team progress.
Profiles use the same dashboard document so local-file navigation preserves your fixed identity and connected folder. Older member.html links redirect there without selecting or changing your identity.
One Work page
Work combines assigned tasks, Inbox, Backlog and Completed. Members start with My tasks; the founder sees Team tasks. Other members’ assigned work remains available in a collapsed read-only list with the existing role checks. Anyone can use Report a bug or idea, including screenshots. Reports wait in Inbox until the founder decides whether to create a task. Creating a task from a report keeps its discussion and screenshots linked in both directions.
Completed lists accepted or released tasks; cancelled tasks remain separate.
Reporting alone earns no XP. Assignment, tests, review and XP rules are unchanged.
Sections have bookmarkable links such as dashboard.html#work/inbox. Old #tickets
links open Inbox and old #work links open assigned tasks, preserving local identity.
Course prerequisites
Course metadata lives in policy.courses: each entry has path (matching the
learning path name), description and requires (other course names). The founder
updates this through record policy.update. The courses array replaces the full
catalogue: read the current policy and preserve all existing entries when editing.
Missing references, duplicate names and circular prerequisites are rejected.
Legacy data without this optional catalogue still loads; unconfigured personal
paths have no automatic prerequisites. No schema migration or progress reset is needed.
Academy and node tools/team.mjs learning --member <id> show locked courses and
what is missing. Unlocks require all prerequisite topics assigned to that person
to be understood or applied, including prerequisite courses further up the chain.
A prerequisite with no topics assigned to that person remains locked; ask the
founder to fix the assignment. Existing histories remain readable when a course
is locked. learning.start, learning.review and learning.apply enforce the gate
in shared core logic. Today suggests only available topics.
The founder’s Academy shows the course catalogue, syllabuses and unlock sequence. Learning still uses explanation, questions, correction and a brief summary; a practical exercise is optional. Course completion adds no separate XP bonus.