Skip to content

Catalog pack format + first pack: food-safety recurring duties (seed-only, no code) #134

Closed

Description

@os-warren

维护者速读

把「岗位履职」从一个客户的空壳变成能直接演示的模板:定义一个只含数据、不含代码的「目录包」格式,并交付第一个包 —— 食品生产企业的食品安全周期性履职项(对应中国《食品安全法》与 HACCP 常见要求)。装上包之后,新用户第一次打开就能看到一套真实、可改的岗位 → 履职项 → 周期,而不是空表。后续 ISO 9001 包和 EHS 包复用同一格式。

Why

Positioning ruling (epic #127): Duly is the standard ObjectStack template app. The competitor is "a spreadsheet plus a chat group". A template with an empty obligation table loses to the spreadsheet on day one; a template that ships a credible, editable catalog of recurring duties for a recognisable industry wins the first five minutes. The catalog must be pure seed data so that a customer swaps it for their own without touching code, and so the AI-authoring path (describe your duties, get a pack) stays open later.

Scope

  1. Pack format — a documented shape under src/seeds/packs/<pack-id>/ (or the equivalent the platform's seeds surface already supports; the dev verifies this first, see Premise). One pack = positions + duty definitions + recurrence rules + default evidence requirements, each as plain seed rows that reference existing objects only. No new objects, no new fields, no hooks. A pack is selectable at boot by one environment variable or one defineStack seed list entry; document which.
  2. Pack README — src/seeds/packs/README.md: what a pack is, the row shape per object, how to author one from a spreadsheet, how to select it, how to remove it. Written for the reader who owns a spreadsheet, not for a platform engineer.
  3. First pack: food-safety — 6–10 positions (e.g. QA manager, production shift lead, warehouse keeper, sanitation lead, maintenance, procurement), 25–40 recurring duties spanning daily / weekly / monthly / quarterly / annual, each with a one-line Chinese and English name and a plausible evidence requirement. Content must be generic and public-knowledge; do not copy any customer's list.
  4. Demo wiring — pnpm demo / pnpm demo:zh boot with the food-safety pack selected so the dashboard, task list and bulk bar show real rows. The empty-first-boot path requested by Make the repository template-shaped: empty first boot, template-readiness checklist, README and getting-started for a reader with their own spreadsheet #132 must stay reachable (pack off = empty).
  5. Translations — every authored pack string passes the existing i18n gates (REENTER table / authored-text coverage); zh-CN is the primary language for the pack, en the secondary.

Premise (verify before coding; report a fork if false)

  • The platform seeds surface in @objectstack 17.3.0 accepts multiple seed files and lets the app choose which to load at boot. If it only supports a single flat seed set, report the fork with the exact import path and symbol, and propose the smallest selection mechanism — do not invent a loader.
  • Current seeds already define at least one position and one duty row that a pack can model its shape on. Name the file.

Acceptance

  • pnpm validate && pnpm typecheck && pnpm test && pnpm build green.
  • pnpm demo:zh with the pack on shows ≥25 duties across ≥6 positions, all labels Chinese, no English leakage beyond the known pie-legend defect (objectui#7696).
  • Boot with the pack off shows an empty obligation table and no errors.
  • README lets a reader add one duty row by editing one file; the dev proves it by adding and removing a throwaway row in the PR description (not committed).
  • No code changes outside src/seeds/**, package.json scripts, docs and translations. Any breach is a stop-and-report.

Out of scope

  • ISO 9001 and EHS packs (separate cards, blocked on this one for the format).
  • Any new object, field, flow or hook. Any UI change.
  • Customer-specific content.

Dispatch notes

Activity

  1. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    Contributor

    Claim: PM loop round 4
    Session: session_011HyoSXGRy6L13mYq1Hp4n1
    Account: os-warren (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-8sm850 (platform-assigned card-thread branch, at origin/main 0ffc92e)
    Worktree: duly-issue-134
    Domain: n/a. objectstack-ai/duly is a single-lane app repo with no domain:*.
    Seat: repo:duly#1
    File surface: new src/data/packs/README.md, src/data/packs/index.ts, src/data/packs/food-safety/pack.ts, test/catalog-pack.test.ts; edits to src/data/index.ts (concatenate the selected pack into dulySeeds; pack off = unchanged), scripts/demo.mjs (default DULY_PACK=food-safety for both demos, only when the caller has not set it), the README.md pointer, and test/demo-seed-opt-in.test.ts only if needed. Not package.json: the default goes in scripts/demo.mjs beside the other demo variables, because shell ${VAR-default} syntax does not run on Windows. No src/translations/ change. Stop on any breach until the seat posts a Claim amendment.
    Container & model: M, mode:thread, model: TIER_DEFAULT (hand-derived), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: Define a data-only catalog pack format selected by DULY_PACK=<id> at compile time, and ship the first pack, food-safety, as duly_catalog_item rows with en and zh inline, with position_code carrying the job positions.
    Thread-read: none
    Premise: Step 0 on 18.2.0 (project file duly-134-pack/step0.md). defineStack({ data }) is one flat Seed[] with no named sets, so selection is an env var read at compile time, like DULY_DEMO_SEED. Positions are free text on the catalog item. Seat rulings on the forks: F1 src/data/packs/. F2 catalog rows only; the dashboard and tasks keep the demo's own rows. F3 inline en+zh with a test that requires both. F4 cite real public frameworks (law, standard number, HACCP principle) and give an article or section only where it is checked against the published text, otherwise the framework alone; the pack README says the pack is a starting point, not legal advice, and the PR flags the citations for domain review. An unknown DULY_PACK id is refused loudly at compile time, never ignored. Pack item names must not collide with the demo catalog's names, since name is the upsert key.
    Serial constraints cleared: #131 (one-boot demo, scripts/demo.mjs) landed as 0ffc92e. #147 holds object, translation and invariants-test files outside this surface. #136 and #137 wait on this card.


    Generated by Claude Code

  2. added a commit that references this issue on Nov 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions