jsonspecs Rule Author
Produce maintainable authoring projects whose executable output is a closed
formatVersion: 2 snapshot accepted by @jsonspecs/rules v3.
Baseline
- Treat
jsonspecs/spec1.0.0-rc.5as the behavior contract and the published@jsonspecs/rulesv3 npm package as the Node.js implementation target. Prefer an npm release plus a lockfile over a GitHub archive unless the task explicitly targets an unreleased revision. - Separate normative snapshot fields from authoring metadata.
manifest.json, source fileid, folders, catalog labels, ownership, package version, and build information are builder conventions; they do not belong in the executable snapshot. - Keep the runtime result closed:
status,issues,ruleset, anderroronly onABORT. Do not addcontrol,trace, engine version, package version, or operator-pack identity to the normative result. - Do not use a CLI release merely because it is named
jsonspecs-cli. Verify that it explicitly builds snapshotformatVersion: 2forspecVersion: 1.0.0-rc.5. Otherwise use project-local scripts or the bundled validation script.
Workflow
- Inspect
manifest.json,package.json,rules/,samples/,operators/,docs/,dist/snapshot.json, and project build scripts before editing. - Confirm the execution boundary: what is validated, what remains application logic, which pipelines are public, and how the snapshot and operator packs are deployed.
- Read
references/rules-v3-contract.md, then build a matrix of exported pipelines, payload paths,$context.*paths, rules, issue codes and levels, dictionaries, conditions, and custom operators. - Keep scenario-local artifacts local. Promote an artifact to
rules/library/only when reuse is real and its field contract and issue meaning are the same. - Update authoring metadata for exports, fields, visible artifacts, and operator descriptions. Never copy that metadata into the snapshot.
- Use built-in operators where possible. For a custom operator, define one immutable
name bound to
{ schema, evaluate }; pass runtime dependencies throughfield,value_field, or namedinputs, and constants throughparams. - Express requiredness with a presence rule. Remember that value operators skip an
absent
fieldorvalue_field; namedinputsare different and let a custom operator observe missing members. - Compose flows with string
steps. Use conditions to gate checks whose meaning depends on type, format, dictionary membership, or another business prerequisite. - Add samples for every exported pipeline: success, each major blocking family, warnings and exceptions where applicable, branch edges, wildcard empty/mixed cases, malformed JSON-safe inputs for custom operators, and every reachable issue code or a documented exclusion with a reason.
- When the contract needs checks outside Rules v3, ship an executable host-boundary
module, call it before
runPipelinein the integration example, and test it together with the rules package. Do not delegate a declared invariant to an imaginary adapter. - Build the snapshot in memory, compute
sourceHashover the whole snapshot withoutsourceHash, compile it with the deployed operator registry, run samples, and compare any checked-indist/snapshot.jsonwith the rebuilt value. - Report boundary decisions, public exports, custom-operator rationale, validation commands, snapshot identity, and residual warnings.
Reference routing
- Read
references/rules-v3-contract.mdfor every Rules v3 or RC.5 task. - Read
references/artifact-layout.mdwhen creating, moving, naming, or migrating artifacts and snapshots. - Read
references/rule-layer-design.mdwhen deciding what belongs in the rules layer. - Read
references/scenario-composition.mdbefore designing exported pipelines, conditions, or reusable validation blocks. - Read
references/guard-patterns.mdwhen ordering presence, type, format, dictionary, date, identifier, wildcard, or cross-field checks. - Read
references/business-language.mdfor catalog labels and issue messages. - Read
references/operator-policy.mdbefore adding or approving a custom operator. - Read
references/issue-semantics.mdfor issue codes, fields, aggregate issues, and multi-field checks. - Read
references/manifest-catalog.mdwhen editing authoring metadata. - Read
references/package-boundary.md,references/distribution-options.md, andreferences/rule-governance.mdfor packaging, deployment, or governance work. - Read
references/validation-checklist.mdbefore final delivery.
Hard rules
- Build a snapshot with exactly
format,formatVersion,specVersion,sourceHash,exports, andartifacts. - Use an object map for
artifacts; remove sourceidfrom each artifact value. - Use a sorted, unique
exportsarray of pipeline ids. Do not use pipelineentrypoint. - Use non-empty string
steps. Do not useflow, object steps, orstepId. - Put
level,code,message, and optionalmetainsiderule.issue. A rule used as a step must haveissue; a rule used only inwhenmay omit it. - Keep issue codes unique across the snapshot.
- Do not use
role,strict,required_context, snapshotmeta,engine, orrequiresin the executable graph. - Add
aggregateexactly whenfieldcontains[*]. UseALL,ANY, orCOUNT. - Do not put
[*]invalue_field, namedinputs, or$context.*. A wildcardnot_emptychecks existing matches only; it does not require a member in every item. - Ensure every artifact is reachable from
exports, includingwhenrules and dictionaries. - Keep package version and operator-pack identity in build/deployment records, not in the normative runtime result.
Bundled validation
Run from a rules project root or pass the project path explicitly:
node /path/to/scripts/audit-manifest-coverage.mjs .
node /path/to/scripts/audit-rule-graph.mjs .
node /path/to/scripts/audit-guard-order.mjs .
node /path/to/scripts/audit-business-language.mjs .
node /path/to/scripts/audit-sample-matrix.mjs .
node /path/to/scripts/validate-package.mjs .
The audit scripts are read-only. Use validate-package.mjs . --static for an untrusted
project: it reads JSON and text only and does not load project JavaScript. Without
--static, the verifier loads the project's installed @jsonspecs/rules and operator
modules, compiles the snapshot, executes samples, and checks committed build files.
Run that mode only for trusted project code. Add --strict to fail on audit warnings.
Neither mode downloads a CLI or writes dist/.
Completion criteria
- The in-memory snapshot compiles under
@jsonspecs/rulesv3 forspecVersion: 1.0.0-rc.5with the deployment's operator registry. - Every export has catalog metadata and executable samples.
- Samples cover every reachable issue code and applicable boundary class, or record an intentional issue-code exclusion with a non-empty reason.
- Required
$context.*dependencies are enforced by rules when absence is a business error and documented outside the snapshot. - Every declared host-boundary check exists as executable, versioned code and is covered by the same test command as the rules package.
- Guard ordering prevents misleading dependent failures.
- Custom operators use the v3 contract and have deterministic pass/fail/skip vectors.
- The full graph is reachable, acyclic, and free of legacy fields.
- A checked-in snapshot, if present, matches the in-memory rebuild byte-for-data after
JSON parsing, including
sourceHash. - The repository's continuous-integration job installs from the lockfile, validates the package, and runs all samples and host-boundary tests on a supported Node.js version.