Imported from welltop-jim-wang/nomicore (
AGENTS.md). Install upstream withnpx skills add welltop-jim-wang/nomicore. Copyright stays with the author.
Agent Instructions
Agent skills
Issue tracker
Issues live in the repo's GitHub Issues (via the gh CLI). See docs/agents/issue-tracker.md.
Triage labels
The five canonical triage labels: needs-triage, needs-info, ready-for-agent, ready-for-human, wontfix. See docs/agents/triage-labels.md.
Domain docs
Single-context layout: root CONTEXT.md + docs/adr/. See docs/agents/domain.md.
Module guidance
Before changing files under packages/, domains/, apps/, or docs/, read the nearest nested AGENTS.md; it defines that module's contract boundaries and verification gates.
Schema authoring
When creating or editing domains/*/schema.vfsl, follow docs/vfsl/schema-authoring-guide.md for modeling, VFSL v1 syntax, carrier selection, doc-comment anchors (including per-member union/enum docs, ADR 0019), generation, and validation.
Nomicore integration skill
When an independent project needs to use Nomicore—author or validate VFSL, generate typed Namespace access, compose Cordis plugins, or configure Hub/Peer replication—use the nomicore skill in .agents/skills/nomicore/; keep the independent project as the owning host.
Typed Namespace writes — mandatory
Every application or independent project that mutates Namespace data must generate the schema projection, load its VfslPathMap augmentation into the consuming TypeScript Program, and pass a projection-aware typecheck; follow .agents/skills/nomicore/typed-access.md and docs/integration/external-project-vfsl-codegen.md. Writes must use generated PathAt/PathPatchValue/PathElementValue types through a host-owned typed adapter over NamespaceLease.mutateData(); this is required, not optional. Reads may use the dynamic NamespaceLease.readData() interface when the caller intentionally handles runtime-shaped data, though typed reads should use generated PathAt/PathValue where static projection is desired. A successful readData delivers value + projection text + truncated — exactly four keys { ok, value, schema, truncated } (ADR 0027): schema is the projection text (投影文本 — a deterministic string rendering of the schema slice and its mounted 数据口径, or strict null when there is no active schema, the path strays off-schema, or the path is hostile), whose trailing ✂ 截断事实: section is the sole carrier of truncation facts (path / cause / omitted count); the structured JSON projection (valueSchema/aliases/docs/aliasDocs four-piece set) and the structured truncations key are retired and are no longer consumption interfaces. The typed-read faces are unchanged: full reads keep generated PathAt/PathValue, budget reads keep DeepOptional<PathAt<…>>; mutation construction never depends on the read delivery form — construct explicitly against the schema, never inherit from a truncated value. When a caller needs a meaningful K-entry slice of a container — the newest K entries (a time field on the map face), a stable key-ordered window, or top-K by a value field — use the lease window reads readArray(path, { n, orderBy, depth?, maxChildrenPerNode? }) / readMap(path, { n, orderBy, depth?, maxChildrenPerNode? }) (ADR 0028) instead of widening a budget: the budget's width is a structurally blind guardrail, a window read is the value-aware selector (CONTEXT.md「窗口读」); n is required (≥1) and the direction rides on the sort term — readMap orders by by:'key' or a single-segment value field, while readArray (only by:'index') orders by the item's own value, so container entries (records) all tie into the index asc anchor and newest-K of record entries belongs to the map face, not the array face. Both deliver the same four-key shape with value as the entry list ({ index, value }[] / { key, value }[] in the ordering basis' order) and schema as the element-scope projection text; entry identity rides along, so [...path, entry.index | entry.key] directly locates the entry for the next deep read or mutation (array indices stay numeric); truncated === kept < total with the ✂ section carrying the window facts (basis + direction + kept/total), and failure is loud instead of absorbed: WINDOW_TARGET_ABSENT (target absent — stop deliberately), WINDOW_CARRIER_MISMATCH (present but wrong carrier — switch to the other API), WINDOW_OPTIONS_INVALID (rule violation — fix the options). For writes, never skip generation or typecheck, widen mutation paths to unchecked arrays, encode array indices as strings ('0' instead of numeric 0), scatter any/casts through business code, access live Y.Doc, edit snapshots, or treat runtime SCHEMA validation as a substitute for compile-time path/value checking. Write-path completion requires generate --check, tsc --listFilesOnly evidence that the exact projection is loaded, and negative type fixtures proving unknown mutation paths and wrong values fail closed.
Third-party plugin hosting
When integrating Nomicore into an external Cordis host, changing plugin assembly, or documenting plugin configuration and shutdown, use Cordis plugin-factory composition and follow docs/integration/cordis-plugin-hosting.md for Instance → Clock/Timer → Persistence → Registry → role-specific replication order, readiness, adapter options, and lifecycle teardown; keep instanceId + role in the Instance service and do not assume a stable dynamic pluginId or cordis_define contract.
Instance replication
When changing Hub/Peer replication, authentication, wire frames, connection or namespace state machines, backpressure, reconciliation, or shutdown drain, treat docs/adr/0010-hub-peer-websocket-ydoc-replication.md as the architecture and docs/protocols/instance-replication-v1.md as the normative wire contract; then read the nearest package or app AGENTS.md. When changing chunked transfer (UPDATE_CHUNK framing, capability negotiation, assembly limits, transfer error codes, or chunked-* observer events), also treat docs/adr/0013-chunked-live-update-transfer.md and docs/adr/0022-chunked-sync-transfer.md as the design contracts.
Namespace diagnostic change log
When changing the diagnostic change log (emission, record schema, adapters, retention, replay, or Registry/Host diagnostic wiring), treat docs/adr/0011-best-effort-namespace-diagnostic-change-log.md and docs/adr/0014-vfsl-validated-jsonl-and-framed-sidecar-change-log.md as the normative contracts, and read packages/namespace-diagnostic-log/AGENTS.md before editing that package. The log is best-effort observability: emit never throws and never changes business outcomes, and lifecycle call sites stay outside the NamespaceRuntime write sequencer slot.
Git worktrees
Create all repository worktrees under the repository-local .worktrees/ directory. Do not create routine worktrees beside the repository or under /tmp. See .agents/WORKTREES.md.