AGENTS.md β chaindoc-labs / esignature-laws
Jekyll-published open dataset and narrative guides on electronic-signature law by jurisdiction. Site is built by GitHub Pages from main; published at https://labs.chaindoc.io.
For human-facing contribution rules see CONTRIBUTING.md and README.md. This file captures only what an AI agent needs that is not obvious from the file tree.
Architecture at a glance
Three parallel surfaces share the same facts:
| Surface | Path | Purpose |
|---|---|---|
| Narrative guide (Markdown) | docs/<region>/<country>.md | Long-form prose, β₯800 words original before βFurther readingβ. |
| Structured law row (JSON) | data/laws.json | Machine-readable summary of the same statute, validated by data/schema.json. |
| Handbook record (JSON) | data/handbook/<country>/<slug>.json | Per-contract-type drafting record, validated by data/handbook/schema.json. Bundled into data/handbook/<country>.json by CI. |
When a narrative is added or changed, the matching data/laws.json row must be updated in the same PR. lastVerified and sources[].accessed should advance together.
Build, validate, run
- Local Jekyll preview:
bundle exec jekyll serve(Ruby 3.3, plugins:jekyll-seo-tag,jekyll-sitemap,jekyll-feed). CI usesjekyll build --strict_front_matterβ frontmatter typos break the build. - Validate datasets (run before opening a PR):
npx --yes -p ajv-cli -p ajv-formats ajv validate \ -s data/schema.json -d data/laws.json -c ajv-formats --strict=false for f in $(find data/handbook -mindepth 2 -name '*.json'); do npx --yes -p ajv-cli -p ajv-formats ajv validate \ -s data/handbook/schema.json -d "$f" -c ajv-formats --strict=false done - Rebuild handbook bundles:
./scripts/build-handbook-bundle.shβ concatenatesdata/handbook/<country>/*.jsonintodata/handbook/<country>.json. CI does this on push forde; do not hand-edit the bundle files. - Rebuild markdown mirror:
./scripts/build-md-mirror.shβ generates the/md/**/*.mdtree served athttps://labs.chaindoc.io/md/...for LLM consumption (linked from llms.txt / llms-full.txt). Files inmd/have no front matter so Jekyll copies them verbatim β never hand-edit them. CI rebuilds on every content push via md-mirror.yml. - Workflows: schema-validate.yml, jekyll.yml, link-check.yml, handbook-bundle.yml, md-mirror.yml.
Project-specific conventions
- Primary sources only. Every cited fact must trace to a statute, regulation, or official court ruling. No Wikipedia, no vendor whitepapers, no law-firm blog posts. If no primary URL exists for a precedent, record
judicial_precedents: [](see docs/eu/germany.md for the pattern) rather than citing secondary commentary. sourcesrequires β₯2 entries in bothdata/laws.jsonrows and in narrative frontmatter. Each entry needsurl,title,accessed(YYYY-MM-DD).-
confidenceishighmediumlow. Uselowif any required fact is supported by only one primary source. country_codefollows^[A-Z]{2}(-[A-Z0-9]{1,3})?$(ISO-3166-1 alpha-2 Β± subdivision).regionis one ofeu,americas,apac,mea.- Disclaimer block (βinformational, not legal advice. Last verified: β¦β) is required at the bottom of every
docs/<region>/<country>.md. - Do not exclude
data/from the Jekyll build β JSON datasets are intentionally web-accessible (see comment in _config.yml). New excludes added to_config.ymlmust not coverdata/. - Layouts auto-assigned by path in
_config.yml:docs/,compare/,industries/,handbook/all default tolayout: page. Do not setlayout:in frontmatter unless overriding.
Adding a new jurisdiction (checklist)
- Create
docs/<region>/<country>.mdwith required frontmatter (jurisdiction,country_code,region,statute,enacted,lastVerified,sourcesβ₯2,confidence,validationConflicts: []). Mirror an existing file such as docs/eu/germany.md. - Append a row to data/laws.json covering the same statute; required fields are listed in data/schema.json.
additionalProperties: falseβ unknown keys fail validation silently in editors but break CI. - Write β₯800 words of original prose before the
## Further Readingsection. - Run the ajv validation commands above locally before pushing.
Adding a handbook record
- Place the file at
data/handbook/<country>/<slug>.json. Files at depth 1 (data/handbook/<country>.json) are bundles, not records β never edit them by hand. schema_versionis currently1.form_requirement.baseβtextform | schriftform | electronic | qualified_electronic | notarial | freeβ these are German civil-law form categories; pick the closest equivalent for non-DE jurisdictions, do not invent new values.- After saving, run
./scripts/build-handbook-bundle.shso the bundle indata/handbook/<country>.jsonmatches your records (CI auto-bundlesde; other countries currently rely on the script being run manually or viaworkflow_dispatch).
Pitfalls
jekyll build --strict_front_matter: any unknown or malformed key in---blocks fails the Pages deploy. Validate locally.- AJV
additionalProperties: falseon both schemas: a misspelled field name (e.g.last_verifiedvslastVerified) is a validation error, not a warning. - Link checker (lychee) runs on
**/*.mdand**/*.htmland opens an issue on broken links β prefer canonical official URLs (e.g.gesetze-im-internet.de,eur-lex.europa.eu,legislation.gov.uk) which are stable, over portal search URLs which are not. - Bundle drift: editing a record in
data/handbook/<country>/without rerunning the bundler leavesdata/handbook/<country>.jsonstale. CI catches this only forde. - Licensing split: content is CC-BY 4.0, code/schema is MIT. When adding files, keep schemas/scripts under the MIT side (no embedded prose from the guides) and prose under the CC-BY side (no copied source code).