Skip to content

feat: seed the local stack with a demo company - #417

Merged
jkobgnther merged 3 commits into
mainfrom
feat/dev-seed
Oct 11, 2026
Merged

jkobgnther merged 3 commits into
mainfrom
feat/dev-seed

Conversation

@jkobgnther

Copy link
Copy Markdown
Contributor

What and why

GRA-430. A fresh vp run dev shows empty pages, so nobody can judge the dashboard, Workflows, Engines or Knowledge against the prototype. vp run seed fills the running local stack with a demo company modelled on the prototype's Noordkade fixtures (mortgage and lending advice). All the data is made up and at acme.test.

What it seeds (scripts/seed/):

  • People (company.ts): 12 people. 2 are admins (the configured admin@acme.test becomes Sanne de Wit, COO), 4 are builders and 6 are users. They sit in five teams: Client onboarding, Mortgage advice, Customer service, Finance and Compliance.
  • Engines (engines.ts): four engines, Client onboarding, Service desk, Finance and Compliance, with seven released workflows between them. Each workflow is real @grasp-os/sdk code with its own workflow-tests, and it makes no external calls: the run's input stands in for what a connection would bring. Five of them ask a team to decide (person params set to the team). weekly-report has a schedule trigger. Each engine has an AGENTS.md, so the Apps collection fills too, and each is shared with its teams.
  • Runs (runs.ts): 163 runs over the last 30 days. Most completed, 13 failed on bad input (an empty email, an invoice without a VAT number, an application without an identity document), and 5 are still waiting on a decision. About 30 decisions are answered, some of them rejected. Each run is real: started through the API by the person the plan names, run by the engine, and answered through the API by a member of the deciding team. Only the times are then moved back in core's local D1, the way core's tests write to it: runs, decisions, failure reports and notifications. Runs fall on working days and keep realistic answer delays; the waiting ones are from the last day and a half, so their deadlines are still ahead.
  • Knowledge (knowledge.ts): four collections, everyone's Procedures plus Finance, Client files and Compliance (sensitive) for teams, with 11 documents. Some have a second version, and some are past their review date.
  • Permissions: Service desk may read Procedures (granted). Finance's request to read its handbook is left waiting, so admins have something on the dashboard pile.
  • Chats (chats.ts): five chats, each created through the API. Their transcripts are written into the person's Workspace object, because asking would call a model. Answers are marked as no model's, the way core marks its own (interruptedMessage).

Safety

  • The seed only reaches http://localhost:5173. The address is hardcoded, never read from the environment.
  • It stops unless core sends sign-in to the local fake IdP, which only a local stack does (devIdpOrigin).
  • It stops unless the signed-in admin is in this checkout's local D1, so it never writes into some other stack's state.

Idempotent: running it again adds only what's missing: people, teams, collections, documents, engines, sharing, params, permissions and chats. An engine gets runs only while it has none. To start over, stop dev and delete apps/core/.wrangler/state. AGENTS.md says this next to vp run dev, and scripts/dev.ts points to the seed.

What's written straight into local state (no API does it): full names and join dates (the fake IdP names people by their email's first word), the run times, and chat transcripts.

Follow-ups, as other streams land: workflow owners and weekly counts (GRA-398/399), Settings sections (GRA-433), and the dashboard layout (#374).

How it was tested

  • Two complete passes, each on an empty stack (apps/core/.wrangler/state deleted, then vp run dev started fresh): vp run seed finished in about a minute. Engines got 50, 57, 34 and 22 runs, and 5 chats were created.
  • A second vp run seed on the same state added nothing: every engine reported "has its runs already" and 0 new chats. No collections, teams or permissions were duplicated (checked in D1).
  • Signing in again keeps the full names.
  • vp check passes (format, lint, types).
  • Screenshots after seeding, signed in as admin@acme.test, at 1440×1000. The session's network policy wouldn't let me upload them, so here is what they show:
    • Dashboard: the pile shows "Finance: read on Collection …" waiting on the admin, with Approve and Reject. The Workflows widget shows 7 workflows: 4 need attention, 2 wait on a person, 1 ran. The Engines widget lists all four engines. "Runs this week" shows a bar chart, "84% without a person of 38 runs".
    • Workflows: all seven workflows with their engine and version 1, last run dates from 5 to 11 Oct, and statuses: Failed, Waiting for a decision (with "2 waiting" and "1 failed in the last 7 days"), and Completed.
    • Engines: four cards with descriptions and their workflow counts (2, 2, 2 and 1), each at version 1.
    • Knowledge: Apps, Client files, Finance, Compliance and Procedures next to the built-ins, with team badges and document titles (for example Approval limits, Coding supplier invoices, Month-end close).
    • Settings → Members and roles: "12 people have access", with full names and Admin, Builder and User roles.
    • Audit trail: filled with the seed's own events (document reads, team, engine and run events).

Running it locally needs vp run dev to start. In a container without Cloudflare credentials, start core with --local the way playwright.config.ts does: core's AI binding is remote.

Checklist

  • vp check and vp test pass. vp check passes; no tests change, and the seed is dev tooling verified by running it.
  • Schema changes are expand-only (no drops or renames in the same release). There are no schema changes.
  • New external calls go through connect; new model calls through the model gateway. The seeded workflows make no external or model calls.
  • No secrets, client names or client configuration. All people and companies are made up, at acme.test.

@greptileai review

🤖 Generated with Claude Code

https://claude.ai/code/session_01DGjkfKxJZ9eCUeQ9YexmJF


Generated by Claude Code

`vp run seed` fills what `vp run dev` runs with a demo company after the
prototype's Noordkade fixtures: 12 people in five teams and three roles,
four engines with released, tested workflows, 30 days of their runs
(completed, failed, and waiting on decisions, most answered), four
Knowledge collections and five chats. Everything goes through core's API
as the person who would do it; only run times, names, join dates and chat
transcripts are written into the local state. It only reaches localhost,
stops unless core signs people in through the local fake IdP, and adds
only what is missing when run again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DGjkfKxJZ9eCUeQ9YexmJF
Copilot AI balanced review requested due to automatic review settings October 11, 2026 20:00

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@greptile-apps

greptile-apps Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 4/5

[Medium impact] Adds seed scripts to populate local development with demo data.

The PR appears safe to merge, with non-blocking fixes for seed recovery, checkout checks, and demo dates.

Findings

  1. P2 Reruns skip unfinished seed work ▶
  2. P2 Wrong checkout gets demo members ▶
  3. P2 Expired decisions keep runs waiting ▶
  4. P2 Completed runs appear in future ▶
  5. P2 Historical results use today's dates ▶
  6. P2 Complaint deadlines count weekends ▶
Fix with agent prompt
### Issue 1
scripts/seed.ts:294-296
After an interrupted seed, `seedEngine` treats any saved run as finished history. It skips the engine even if decisions were never answered or dates were never moved. The other existence-only checks also skip an ungranted `PROCEDURES` request, an empty chat, or a document missing its second version.

Track completed seed work, or resume unfinished steps without duplicating or overwriting existing data.

### Issue 2
scripts/seed.ts:122-125
If another checkout is running on port 5173 and this checkout has old local state, `seedPeople` signs all demo people into the other stack before checking which checkout owns the server. Those sign-ins create members. The later check throws but leaves them behind.

Open the admin session and check its local state before signing in the remaining people.

### Issue 3
scripts/seed/runs.ts:245-258
`backdate` moves an open decision's `expires_at` but leaves the engine's saved wait unchanged. After the moved deadline passes, people cannot answer, yet the engine can keep waiting until the original deadline, up to 36 hours later.

Move the engine's wait along with the displayed deadline, or keep both on the same clock.

### Issue 4
scripts/seed/runs.ts:85-94
On a Monday before 05:00 UTC, `startTimes` includes that morning's scheduled run even though its start time is still ahead. Scheduled times are not capped at `now`, so a completed `weekly-report` can appear to have started in the future.

Filter out Mondays whose scheduled time has not arrived.

### Issue 5
scripts/seed/engines.ts:739-740
All four historical `weekly-report` runs pass empty input, so every result names the current week despite different Monday start dates. Complaint results also calculate `acknowledgeBy` from today's date before their runs are moved into the past. Moving the row dates does not change those results.

Supply each planned run's date to these demo workflows so their results match their history.

### Issue 6
scripts/seed/engines.ts:411
`complaint-acknowledgement` promises two working days but adds two calendar days. A complaint registered on Friday gets a Sunday deadline instead of Tuesday.

Skip weekends when calculating `acknowledgeBy`, and add a Friday test case. The current tests replace the date calculation with a mock.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

Adds vp run seed to fill the local stack with a demo company.

  • The local stack gains demo people and teams.
  • Knowledge opens with team collections and sample documents.
  • Demo engines run workflows and show a month of activity.
  • People can open chats with ready-made conversations.

Acknowledged intent: jkobgnther explicitly states, “An engine gets runs only while it has none.” Skipping an engine that already has ordinary runs is intentional. The rerun finding concerns unfinished seed work, not that policy.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A["vp run seed"] --> B["Sign in through local fake IdP"]
  B --> C["Check admin against local D1"]
  C --> D["Create people, teams and Knowledge"]
  D --> E["Release and share engines"]
  E --> F["Start runs and answer decisions"]
  F --> G["Move dates in local D1"]
  G --> H["Seed permissions"]
  H --> I["Create chats through API"]
  I --> J["Write transcripts into Workspace storage"]
Loading

Reviews (1) · Last reviewed commit: "feat: seed the local stack with a demo c..." · Reviewed by Greptile

Comment thread scripts/seed.ts
Comment thread scripts/seed.ts Outdated
Comment thread scripts/seed/runs.ts
Comment thread scripts/seed/runs.ts
Comment thread scripts/seed/engines.ts
Comment thread scripts/seed/engines.ts Outdated
…he same

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DGjkfKxJZ9eCUeQ9YexmJF

Copy link
Copy Markdown
Contributor Author

check failed on one test this PR doesn't touch: apps/core/test/build-jobs.test.ts › "holds a chat to three running jobs, submitted at once too, and frees the place of one whose instance ended". It failed with instance.not_found from the Workflows binding, and Vitest also reported an unhandled deleteAllDurableObjects() rejection from reviewed-calls.test.ts.

The other 4,599 tests passed. This PR changes only scripts/seed*, scripts/dev.ts (a comment), AGENTS.md and package.json; none of that is loaded by core's workerd tests. The test came in with #409/#411 and races a terminated instance against its record, which looks like timing on a loaded runner. I haven't found an open fix for it, and main can't confirm it either way: check is skipped on main pushes.

I'm re-running the failed job once. If it fails again, I'll treat it as real and look into it.


Generated by Claude Code

… only to this checkout's stack

- complaint-acknowledgement takes the day a complaint came in and counts two working days from it;
  weekly-report runs get their own Monday, so results match when the runs are shown to start
- an open decision keeps the deadline its engine waits until
- a Monday's scheduled run counts only once its 7:00 has passed
- the admin's sign-in checks the stack is this checkout's before anyone else signs in

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DGjkfKxJZ9eCUeQ9YexmJF
@jkobgnther
jkobgnther merged commit 363ade6 into main Oct 11, 2026
8 checks passed
@jkobgnther
jkobgnther deleted the feat/dev-seed branch October 11, 2026 22:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants