Contributing

Contributing

Before any of this, read UPDATE.md at the root of the tree. It is the standard for updating a skills tree of this shape — the four questions asked in order, what may be added and what may not, how an id is modified and how one is retired, the evidence bar, enforcement before advice, and the pre-commit checklist — and this page does not restate it. What follows is only the mechanics of this repository: which commands run, which templates apply, and where a rule or a workflow example is filed.

Every change to this tree lands with a green npm test. INDEX.md states the standard without a grace period: npm test “is green at the published head or the head is not publishable.”

What npm test runs

From package.json, in order: routing validation, resources validation, the knowledge citation check, alias validation and the alias doc --check, operator validation, workflow validation, the operators index --check, template validation, every operator’s self-test, and the script specs (node --test scripts/*.spec.mjs).

Two of those are regeneration checks rather than assertions: operators/INDEX.md and alias/INDEX.md are generated files, and a stale one fails the build. The docs generator on this site works the same way — node docs/scripts/generate-docs.mjs --check.

Templates

Nothing authored in this tree is free-form. templates/ holds one template per document kind, each carrying a fenced json template-contract block that scripts/validate-templates.mjs enforces on every file the template applies to and on that file’s .vi.md mirror. To change a shape: change the contract, run node scripts/validate-templates.mjs, and bring every document it names into conformance in the same commit. “A template that the tree does not satisfy is not published.”

scripts/validate-templates.spec.mjs proves the validator itself on a synthetic tree, so a missing section, a wrong order, a wrong table header, an extra table under a rule, and a missing mirror each fail with the line that names them.

Adding a knowledge rule

A rule is an address, not a paragraph. The constraints that hold everywhere:

  • Append the next sequential PREFIX-n. “Rule IDs are stable public addresses. Append; never renumber, reuse, or silently change meaning.”
  • Write it into the file its reader binds — composition, presentation or proof for ui/; the family file for grammars/; the topic file for patterns/.
  • Give it the table its template requires: Case | When | Assert for composition, Case | When | Owner | Render for presentation, Case | When | Observe for proof, Case | Rule | Common owner | Core realization for grammars, Case | When | Write for patterns.
  • Bring the evidence. knowledge/patterns/ rules were “extracted from starci-academy-fe/src/ and starci-academy-fe/packages/grammar/src/ by opening files and counting, and each table cites the files it was read from”; a pattern rule cites two real paths, and where the code is split the file records the dominant variant with its count instead of legislating. scripts/validate-knowledge-citations.mjs runs inside npm test.
  • Write the .vi.md mirror in the same commit. It is a human reading copy, never runtime authority.

A rule that no operator’s bound inventory can reach is not a rule; it is a file nobody reads.

Adding a workflow example

A composed chain that would be useful again becomes a file in workflows/, with its when in both en and vi. It must satisfy everything scripts/validate-workflows.mjs checks: every branch names a real operator and presets only fields that operator declares, every required Input is produced by an earlier step, branches of one step share no write alias, every loop goes back to an earlier step with a maxRounds, and the chain ends at git.publish, release.deploy, or user. Add the row to the table in workflows/README.md and its Vietnamese mirror.

Documentation

docs/ is this site’s source. Hand-written pages live at the root and under concepts/; everything under docs/reference/ is generated by docs/scripts/generate-docs.mjs and must never be edited by hand. The rule for a hand-written page is the same one the tree lives by: where a rule exists in a file, quote the file or link to it. A page that restates a rule in its own words has become a second home for that rule, and second homes go stale.

To work on the site:

cd sites/docs
npm install
npm run dev        # regenerates the reference pages first
npm run build      # static export to sites/docs/out
npm run check      # fails when the committed reference pages differ from the tree