Development standards
Development standards (NDD) are your project's code rules: one family per language, each rule with its level and its "why". You come to this path so the agent knows which rules apply to a task, to fetch the standards of a shared repository, or to evolve a rule.
What you ask the agent
« Which standards apply to the task you are about to do in codebase/api/? »
« List all the Rust rules, with their text. »
« Import the Rust standard of the api module from my standards repository. »
« Use this standards repository for all my projects: git@example.org:me/standards.git. »
« Update this project's standards from the shared repository. »
effortless_ndd_sync« Propose making rule RUST-12 of the rust standard mandatory, because swallowed errors cost us a lot: "Propagate errors — every error is propagated or logged." »
effortless_ndd_amendment_proposefamily=rusttarget_id=RUST-12proposed_id=RUST-12level=OBLIGATOIREtitle=Propagate errorswhy=Swallowed errors cost us a lotbody=Every error is propagated or logged.
« I accept the amendment AMD-03 you just proposed. »
« Reject amendment AMD-03: we do not want this rule for now. »
effortless_ndd_amendment_rejectproposal_id=AMD-03reason=We do not want this rule for now
What the agent does
Find out which standards apply
effortless_ndd_resolve: read-only. The agent passesstack(the families to resolve, named like the folders of.ai/ndd/) orpath(a project path from which it derives the families). With neither, it gets the whole known corpus.- Each rule comes back qualified: identifier, level (
OBLIGATOIRE,RECOMMANDÉorINTERDIT), title, why, family, origin, file and line. The full text is served only if the agent passesinclude_body: true.
Import a standard from a shared repository
- The address of the standard is declared in the stack, under
languages[].ndd.source. If it is missing or must change, the agent fixes it witheffortless_stack_declare_languages(see Code and stacks). effortless_ndd_importwithstack_idandtechno(the language, which also gives the family name). The verb reads the file from the repository withgit show, without cloning or fetching the repository, and writes the inherited standard to.ai/ndd/<family>/<family>-ndd.v1.heritee.md, with a provenance file (repository, reference, date).- If the git reference cannot be found, the import breaks nothing: the response carries
available: falsewith the reason, and no file is written.
Follow a shared standards repository
effortless_ndd_sourcedeclares the global source: a local folder or a git URL, withreferencefor a branch or tag. Withoutsource, it reads the current source; with an empty string, it removes it. A project can override it withsettings.ndd_sourcein itseffortless.json.effortless_ndd_syncupdates the project's inherited standards for each language present (declared stacks, families already there, and theagnosticfamily). It returns the families updated, unchanged, and those the repository does not carry. It never touches the local standard.
Propose, accept or reject an amendment
effortless_ndd_amendment_proposewithfamily,proposed_id,level,title,why,body, andtarget_idif the amendment changes an existing rule (absent: new rule). The text is analyzed the wayeffortless_ndd_resolvedoes. Only the.effortless/ndd_amendments.jsonregistry is written (status Proposed); no standard file is touched.effortless_ndd_amendment_acceptwithproposal_id. The content is always written on the local side (.ai/ndd/<family>/<family>-ndd.v1.md), never in an inherited file: amending an inherited rule means overriding it locally. Same identifier as the target: the section is edited in place. Different identifier: a new section is added, the old one is not touched.effortless_ndd_amendment_rejectwithproposal_idandreason. The reason is recorded word for word with the date; no standard file is opened for writing.
The agent never accepts or rejects an amendment on its own: the decision is yours, and it carries it out after your agreement.
What you get
- A clear list of rules before the work, instead of a guessed standard.
- In the project: files under
.ai/ndd/(local and inherited standards, plus the provenance of the inherited ones) and the.effortless/ndd_amendments.jsonregistry. - In the app: the address of the shared repository is set in Preferences › Standards (see Profile and preferences), and the Modules screen shows the Standards present for each module.
When the agent is refused
| Situation | What the refusal says | What to do |
|---|---|---|
| No standard in the project | ndd:aucuneNorme | Import or sync a standard (effortless_ndd_import, effortless_ndd_sync). |
| Requested family unknown | ndd:familleInconnue (the response lists the available families) | Pick stack or family among the listed families. |
| Rule level out of the standard | ndd:niveauInconnu (file and line named) | Fix the line: the level must be OBLIGATOIRE, RECOMMANDÉ or INTERDIT. |
| Rule without a "Why" | ndd:pourquoiAbsent | Add the "Pourquoi :" line to the named rule, or pass why to a proposal. |
| Two rules with the same identifier | ndd:identifiantEnDouble (both locations named) | Rename one of the two identifiers. |
| Unknown stack on import | ndd:stackInconnue | List the stacks with effortless_stack_list. |
| Language missing from the stack | ndd:languageInconnu | Declare the languages with effortless_stack_declare_languages. |
| Standard source is not git | ndd:sourceNonGit | Declare the source as git for this language; the import accepts only that. |
| Standards source not found or unreachable | ndd:sourceIntrouvable, ndd:sourceInjoignable | Fix the address with effortless_ndd_source (existing folder or git URL) and check your git access. |
| Corporate certificate not recognized by git | ndd:certificatNonReconnu | Install the company root certificate, or declare it to git, then run effortless_ndd_sync again. |
| Amendment: targeted identifier not found | ndd:identifiantViseInconnu | Look the identifier up with effortless_ndd_resolve. |
| Amendment: unknown proposal | ndd:propositionInconnue | Use the identifier returned by effortless_ndd_amendment_propose. |
| Amendment: already accepted or rejected | ndd:amendementDejaArbitre | No action reopens it; a new proposal opens a new amendment. |
| Rejection without a reason | ndd:amendementRejectReasonRequired | Give reason. |