@encore-os/eos-spec

中文文档
0.33.2发布于 2026/10/17SEE LICENSE IN LICENSETypeScriptES Module近 30 天下载 3517

Portable, config-driven spec-pipeline engine + quality harness. One canonical engine consumed as a library (with a client-safe /pure subpath) by every Encore-OS repo.

原始使用文档
文档目录11 节
  1. Quickstart — with a coding agent (recommended)
  2. Quickstart — manual
  3. Machine contract
  4. Entry points
  5. Precedent & semantic search
  6. Create gates: precedent block mode
  7. Gate triggers: the triggers: block
  8. UI-evidence legs (per layout)
  9. Scorecard credit: the verifies: block
  10. Companion skills
  11. Versioning & release

@encore-os/eos-spec

A portable, config-driven spec-pipeline engine + quality harness. It ships two faces from one package: an agent-friendly CLI (eos-spec) and a library (with a browser-safe /pure subpath). The package carries no corpus data — it drives any repo's specs/ tree as described by that repo's specs/config.yaml.

Specs move through a pipeline (stub → clarified → validated → … → tasks_generated); the engine derives each spec's stage from signals in its markdown, recommends the next action (blocker-aware), and gates completion claims against on-disk evidence.

npm install -D @encore-os/eos-spec   # or run everything via npx
npx @encore-os/eos-spec setup        # prints the onboarding plan
npx @encore-os/eos-spec setup --yes  # scaffold layout + AI_GUIDE.md + install spec-pipeline-skills (Claude Code)

Then prompt your agent — e.g. "Read AI_GUIDE.md and use eos-spec to create and drive a spec for ." The generated AI_GUIDE.md teaches the agent the loop: profile --json first, then next / run, always --json, switching on machine error codes.

Quickstart — manual

npx @encore-os/eos-spec init --scaffold      # specs/config.yaml + templates + per-core dirs
npx @encore-os/eos-spec create APP-01 "First feature"   # `app` is the scaffolded default core
npx @encore-os/eos-spec validate --core app
npx @encore-os/eos-spec next --spec APP-01   # the one recommended next action

eos-spec --help lists a worked example for every command.

Machine contract

Every command accepts --json and emits one stable envelope:

{ "ok": true, "data": { "…": "…" } }
{ "ok": false, "data": null, "error": { "code": "SPEC_NOT_FOUND", "message": "…" } }

Error codes are a frozen, append-only enum (SPEC_NOT_FOUND, UNKNOWN_CORE, INVALID_ARGUMENT, SCOPE_REQUIRED, VALIDATION_FAILED, DUPLICATE_SPEC_ID, SUBPROCESS_ERROR, IO_ERROR, ENGINE_VERSION_MISMATCH, INTERNAL, GATE_HALT) — switch on error.code, never regex the text. GATE_HALT is run stopping at a compliance/research governance gate it never clears: a human clears it, then re-runs. Skills that wrap this CLI pin their supported engine range with the global --require-engine ">=0.23 <1" flag; a mismatch fails fast with ENGINE_VERSION_MISMATCH.

Entry points

  • @encore-os/eos-spec — fs-bound main entry: the CLI program plus the corpus API (listSpecs, findSpec, loadConfig, …).
  • @encore-os/eos-spec/pure — fs-free re-exports only; safe to bundle in a browser app. Enforced by a purity test on transitive value imports.
  • @encore-os/eos-spec/embeddings — narrow fs-bound subpath for a corpus-local embeddings build + recall, without dragging in the CLI graph.

The precedent command searches active + archived specs, registry, and deferred dashboard for prior art:

  • precedent --spec <id> — Lookup precedent for one spec (identifier overlap). Returns specs sharing backtick-quoted table identifiers, ranked by document frequency (distinctive shared tables rank higher).

  • precedent --topic <text> — Lookup precedent for a topic keyword (ranked search). Ranks results semantically when vectors + embedder are available (via live query embedding with Ollama); lexical fallback when either is absent. The output carries a rankMode field ('semantic' or 'lexical') to signal which method ranked the hits. When ranking semantically, archived specs are not in the embedding corpus; status metadata may show 'unknown' for semantic hits.

Both modes support --core <core> to scope search to one core. The --all flag lifts the default cap (15 top matches).

Create gates: precedent block mode

Repos can declare a create_gates block in specs/config.yaml to opt into block mode for the create command's Tier-2 precedent auto-check:

create_gates:
  precedent: block            # 'warn' (default) | 'block'
  precedent_block_min_score: 12
  • precedent: 'warn' (default) — Surfaces prior art but never blocks. Shows top lexical hits when a spec ID or title has a near-duplicate precedent.

  • precedent: 'block' — Halts create (non-zero exit, no scaffold) when the top lexical hit's score clears precedent_block_min_score. The --force flag overrides (logged). Fail-open on config/search errors.

  • precedent_block_min_score — Lexical score floor (searchSpecs' score field); default is 12. A bare title match never reaches 12 alone — the floor requires genuine two-signal corroboration (title AND body). Pass create <id> --force to force-create despite a high precedent hit.

Exactly one create-precedent gate event is logged per invocation, regardless of whether the check warns or blocks.

Gate triggers: the triggers: block

The classifiers that put a spec in scope for a gate or cap (regulated, sensitive, UI-bearing) and the compliance switch are declared in specs/config.yaml. Every key is optional; an absent block or key keeps the engine default shown here:

triggers:
  regulated_cores: [cl, pm, hr, rh, gr]   # each must be a core declared in `cores:`; [] = none
  sensitive_tags: [sensitive, phi, pii, billing, credentialing]
  sensitive_fields: []                    # frontmatter keys; `phi: true` opts a spec in
  sensitive_keywords: true                # the HIGH/LOW content heuristic
  ui_paths: ['\/(components|pages|wizards)\/', '\.tsx$']   # over each affected_files entry
  ui_headings: ['UI\s*(?:\/\s*)?UX\b']    # an h1–h3 heading TITLE (see "UI sources" below)
  ui_id_patterns: ['-UX-']                # over the resolved spec id, case-insensitive
  ui_ux_dir: true                         # a spec under specs/<core>/ux/ is a UI source
  ui_inference: warn                      # off | warn ('cap' is reserved and rejected)
  compliance: true                        # D12: only a literal `false` turns compliance gating off
  • Validation is strict and fail-closed. An unknown key, a key present with no value, a non-list, a blank entry, an undeclared core, a quoted "false", or a pattern outside the engine's linear-time regex subset fails every command with VALIDATION_FAILED (exit 2) and lists each issue; doctor reports them as findings instead. An engine that validates the block rejects a key it does not know, so a config that uses a key from a newer engine fails loudly there; engines released before the block existed ignore it entirely (compliance and regulated gating stay on). Pair a config that relies on a key with --require-engine.
  • Patterns use a safe subset: no lookarounds, backreferences, counted or lazy repetition, nested repetition, or adjacent quantifiers that can match the same character (\s*\/?\s*, a*a*); at most 200 characters and 16 quantifiers.
  • The keyword scan reads the whole file, frontmatter included, so a tags: [phi] line keeps a spec keyword-sensitive even when phi is not in sensitive_tags. A tag-free sensitivity definition also sets sensitive_keywords: false.
  • compliance: false turns compliance gating off in one place: the compliance-review stage stops applying, isComplianceGated is false in next/status JSON, run never walks strict, the backfill preempt counts a spec review, and close-out never caps on a missing compliance sign-off. The classifiers themselves do not change.
  • UI sources. A spec is UI-bearing (the UX cap and the UI-evidence tail apply) when any of these holds: it declares ui_bearing: true; an affected_files entry matches ui_paths; a heading matches ui_headings, plain or after a section number (## UI/UX, ## 5. UI/UX, ### 8A) UI / UX); its id matches ui_id_patterns; or it lives under specs/<core>/ux/ while ui_ux_dir is on. Only one source is inferred: a body that names a UI path (a non-test .tsx file, or a src/ or @/ path through components/, pages/ or wizards/). It never caps. On a spec that is not UI-bearing and not ui-gate-waived, it raises a warn-only ui-inferred-undeclared note: declare ui_bearing: true, or eos-spec signoff --type ui-gate-waived --spec <ID>. The note appears in next/status (data.triggers, data.triggerNotes, data.triggerNoteCounts), audit (rows[].advisory and an advisories block) and doctor (data.advisories). It never changes an action, ok or an exit code.
  • Turning UI sources off. ui_inference: off skips only the body-path scan, which silences the notes; every other source still makes a spec UI-bearing. Those are switched by their own keys: ui_id_patterns: [], ui_ux_dir: false, or a narrower ui_headings or ui_paths list (a ui_headings entry matches both the plain and the numbered heading). For a single spec, eos-spec signoff --type ui-gate-waived --spec <ID> lifts the UX cap and the UI-evidence tail; the spec stays UI-bearing.
  • The per-spec markers (<!-- sensitive -->, <!-- not-sensitive -->, ui_bearing: true, <!-- ui-gate-waived: -->) are always honored.
  • profile --json projects the resolved block as triggers. These commands read it from the --config file: next, status, run, proceed, reconcile, funnel, signoff, close-out, backfill, scorecard (with --rtm), readiness-rollup, mission-status, list, audit, complete, doctor and profile. The rest (ready, validate, walkthrough, precedent, create, …) read it from specs/config.yaml, as their core list does. When one of them walks the spec corpus, an invalid block there fails it with VALIDATION_FAILED (exit 2) even when --config names a valid file; create then scaffolds nothing.

UI-evidence legs (per layout)

A UI-bearing spec owes UI evidence before it completes. The default legs are docshots, a browser auto-heal sign-off (heal-verified) and a filmed walkthrough (video-walkthrough, or walkthrough-waived); ui-gate-waived escapes all of them.

  • The legs are layout data, not config: PipelineSchema.uiEvidence declares the legs a layout owes, in the order next asks for them, with each leg's actor, reason and invocation. A layout that omits it owes DEFAULT_UI_EVIDENCE_LEGS: the three above, with encoreos-shaped invocations (tests/e2e/<core>/*-docs-shots.spec.ts, npm run docs:shots:check). Both built-in layouts (encore1, builder) omit it.
  • next --spec routes a spec whose tasks are done to its first owed leg (capture-docshots, browser-autoheal, record-walkthrough). A leg the layout does not declare is never emitted. A create-wizard's submit→DB E2E (submit-e2e) is not UI evidence: it keeps its own check and submit-e2e-waived escape, right after the docshots leg (before the first leg when a layout declares no docshots).
  • complete --enforce refuses completion while a leg the repo's layout declares is owed. If the layout cannot be resolved, it requires all three.
  • Library: uiEvidenceMissing(spec, legs?) and uiEvidenceGate(spec, legs?) take the leg ids (default: all three, so one-argument calls are unchanged); ResolvedPipeline.uiEvidenceLegs is a layout's set and renderUiEvidenceInvocation fills an invocation's ${id} and ${idLower}.

Not in the engine yet. These are owner-gated follow-ups:

  • K1, encoreos adoption. An engine bump that adds the specs the numbered-heading, -UX- id and ux-dir sources now cap to its UX deferral list, replaces its copied UI heuristic with classifyUiBearing, derives its regulated-core lists from the engine (profile --json or resolveTriggers), and picks its compliance definition (its own in triggers:, or the engine default).
  • K2, builder adoption. triggers: { compliance: false } (optionally ui_inference: off), and Spec Studio passing the triggers, the spec flags and the layout's isComplianceGated, and picking its layout from pipeline.layout.
  • C7, builder's own UI-evidence legs. Until BUILDER_PIPELINE_SCHEMA.uiEvidence declares them, a builder repo is asked for the default (encoreos-shaped) legs.
  • Phase 3, full inference capping per repo. Body-path inference stays warn-only (ui_inference: cap is reserved and rejected) until its gates hold and the owner approves that repo's flip.

Scorecard credit: the verifies: block

scorecard and readiness-rollup give a @verifies backing file credit only when it declares at least one test that would run. They read the file statically: a generated skeleton, a generator placeholder, or a file whose every test(/it( is a fixme, a .skip/.todo, an unconditional self-skip, or sits inside describe.skip( / test.describe.skip( / test.describe.fixme( earns none. Other commands credit every backer.

A suite whose only tests a helper declares for it reads as a stub unless the repo names that helper:

verifies:
  registrars: [registerOrgScopedRlsSmoke]   # default: [] (no registrars)
  • A call to a listed name that passes an inline function as any argument (registerOrgScopedRlsSmoke(table, () => ctx)) counts as a would-run test, under the same skip rules as it/test. Without a function argument (registerX(table, ctx)) it does not count.
  • Each entry must be a bare JavaScript identifier. Other entries are dropped, as is a value that is not a list. The callee must also be called bare: helpers.registerX( and registerX<T>( are not matched.
  • Library callers pass the list themselves: scanVerifies(root, roots, { excludeStubBackers: true, registrars: verifiesSettings(config).registrars }).

Companion skills

The encore-plugins marketplace ships spec-pipeline-skills — nine Claude Code skills that drive this engine (setup --yes installs them):

claude plugin marketplace add Encore-OS/encore-plugins
claude plugin install spec-pipeline-skills@encore-plugins --scope user

Versioning & release

SemVer. Releases are cut by release-please and published to the public npm registry on tag; the CHANGELOG is generated — behavior changes ride Conventional Commit PR titles. Node ≥ 22, ESM only.

版本与发布记录

@encore-os/eos-spec 共发布 43 个版本,首次发布于 2026/06/23;过去 12 个月发布了 43 个版本。

版本发布日期距今
0.33.2latest2026/10/1727 天前
0.33.12026/10/1727 天前
0.33.02026/10/1529 天前
0.32.02026/10/051 个月前
0.31.02026/09/301 个月前
0.30.02026/09/301 个月前

关于 @encore-os/eos-spec 的常见问题

@encore-os/eos-spec 是什么?

Portable, config-driven spec-pipeline engine + quality harness. One canonical engine consumed as a library (with a client-safe /pure subpath) by every Encore-OS repo.

如何安装 @encore-os/eos-spec?

在项目目录运行 npm install @encore-os/eos-spec,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:yaml(^2.8.4)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。它还提供命令行工具 eos-spec,可以用 npx eos-spec 直接运行。

@encore-os/eos-spec 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@encore-os/eos-spec 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@encore-os/eos-spec 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@encore-os/eos-spec 可以商用吗?

@encore-os/eos-spec 使用 SEE LICENSE IN LICENSE 许可。许可条款写在包内的独立文件中,请阅读该文件确认可否商用。以上为概括,不构成法律意见,请以许可原文为准。

@encore-os/eos-spec 的下载量有多少?

根据 npm 官方下载统计,@encore-os/eos-spec 在 2026/10/14 – 2026/11/12 这 30 天内被下载 3,517 次,日均约 117 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@encore-os/eos-spec 还在维护吗?

最新版本 0.33.2 发布于 2026/10/17(27 天前);至今共发布 43 个版本,其中过去 12 个月发布了 43 个;首次发布于 2026/06/23。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。