O.G.A.S. Русский

Rules of development

The document sets the required rules by which the parts of the O.G.A.S. platform are made, by which the platform behaves toward the person, and by which development and documentation are carried on. The rules hold for all parts of the platform, for the development tools and for the documentation.

1 General provisions

1.1 The purpose of the rules

1.1.1 The rules give the platform three properties:

1.1.2 A rule that serves none of these properties is not included in the document.

1.2 Scope

1.2.1 The rules hold for the following parts:

1.3 Terms and definitions

1.3.1 The document uses the terms given in table 1. The other terms — by Terms.

Table 1 — Terms of the rules

Term Definition
Part A unit of the platform working on its own: the kernel, the common code of the protocol, a function of the platform, a module, the common code of modules, the workshop
Element A finished unit that takes a ready place as one folder: a module, a function of the platform, a kind of node, a window of the workshop, an element of the pulpit, a working process
Component A file or folder inside a part that has one task
Code of a part The source texts of a part, its dictionaries, its settings schema, its description of itself, its checks
Contract A way the parts interact, described in the documentation: methods, events, formats of documents, constants of the contract
Constant of the contract A value all parts must understand alike: the version of the protocol, the name of a document format, an error code, the name of a method, the limit of a message length
Setting A value a person or another program may need to change; declared in the settings schema of its owner
Inner quantity A value only the developer of a part needs: a polling step, a buffer size
Owner The part that alone writes a document, a setting or a value and answers for its meaning
Ready place A list elements of one sort are added to: the register of functions, the set of kinds of nodes, the folder of modules, the windows of the workshop
Sign A fact about a part that it declares itself in its description and by which other parts choose their behaviour: a flag, a role, a right, a prefix
Dependency A condition declared in the description of a part that its work needs another part
Person Whoever uses the platform
Product owner The person who makes decisions about the product
Developer The developer who carries on the code and the documentation by these rules
Documentation The documents listed on the map of the documentation (docs/README.md)

1.4 The order of applying

1.4.1 All rules are required. The degree of obligation is expressed by three wordings:

There are no other wordings of obligation («preferably», «if possible», «as a rule») in the rules.

1.4.2 A prohibition holds at once for code, documentation and interface, unless the rule says otherwise.

1.4.3 Each rule holds a list of signs of breach. Conformance is checked by this list: at least one sign means a breach.

1.4.4 A departure from a rule is allowed only by a decision written in the journal of decisions. The record names the number of the rule, the reason and the bounds of the departure. A departure without a record is a breach.

1.4.5 A breach that is not removed at once is written into the list of nonconformities.

1.4.6 A document of a part may add to these rules and may not contradict them. On a contradiction the document of the part is corrected.

1.4.7 A rule is referred to by the number of its subsection: «rule 2.6».

2 Requirements for the make-up of parts

2.1 Division into components

2.1.1 A part must be divided into components so that each component has one task. A task is described in one sentence; if in the description the conjunction «and» joins different actions, these are two tasks.

2.1.2 A task without subtasks is done in one file. A task with subtasks is done in a folder: in it the main file and a file per subtask. The depth of nesting must repeat the structure of the task and must not exceed it.

2.1.3 The main file of a part (main.rs, main.py, app.js) must only start the part, take messages and pass each to the component whose task it is. Computation, checking, keeping data and declaring the state of a service are not allowed in the main file.

2.1.4 Components are divided by tasks, not by size. It is not allowed to split a file only because it is long, and not allowed to make a file that has no task of its own.

2.1.5 The name of a component must name its task. Related components must lie side by side, unrelated ones in different places.

2.1.6 Signs of breach:

2.2 Values and texts outside code

2.2.1 Everything that may need to be changed must be changed without editing code. Values and texts are kept in separate files, and code gets them from there.

2.2.2 A value is of one of three kinds. Where each kind is declared and how it is changed is given in table 2.

Table 2 — Kinds of values

Kind Where declared Who changes it and how
Setting The settings schema of the owner: key, default, allowed values. The name and the hint — in the owner's dictionary under the keys setting.*. The chosen value is kept in the files of the levels of settings The person — in the workshop or in the file of a level
Constant of the contract At the owner of the contract: error codes — in its codes.rs, the rest — in its constants file. A constant that dependent parts name too the owner declares in the common code of the protocol, in the section of its contract core/protocol/src/contracts/<owner>/: only the owner writes, the dependent ones read by name, there are no copies. What is common to all parts — in the common code of the protocol. The contract in the documentation lists the same constants Only by a decision together with a new version of the contract
Inner quantity The constants file of the part: the name and an explanation why this value is chosen The developer

2.2.3 The kind of a value is found by a question: will anyone but the developer have a reason to change it? If so, the value is a setting. If not, the value is an inner quantity and is declared with a name in the constants file.

2.2.4 Texts for the person (labels, names and hints of settings, error messages) must be kept in the owner's dictionaries: locales/ru.json and locales/en.json. Code and the settings schema hold only the key of a text.

2.2.5 Service text (a record of the kernel journal, command line output, an explanation for the developer inside an error) is written in code in English and is not put into dictionaries.

2.2.6 Code must get a setting through the owner of settings, a text through a dictionary, a constant by name from the constants file. Own defaults, limits and fallback texts in code are not allowed.

2.2.7 If the owner of settings is unavailable, code takes the default and limits from the same settings schema through a common helper. A second copy of a default is not allowed.

2.2.8 Signs of breach:

2.3 Parts interact only through the contract

2.3.1 Parts must interact only through the contract. It is not allowed to read the files of another part, link its code, write into its documents and use its inner data.

2.3.2 A method, field or event that is not in the description of the contract is a breach, even if the code works.

2.3.3 The dependency of a part on another part must be declared in the description of the part; for a function of the platform — in the field requires of the file function.json. Hidden dependencies are not allowed.

2.3.4 If a part is unavailable, the other parts must go on working and show the person what is missing.

2.3.5 A part that failed must report the failure with an error with a code, the place of the failure and a sign whether a retry will help. The failure of one part must not stop others.

2.3.6 Signs of breach:

2.4 A single owner

2.4.1 Each document, setting, value and action must have exactly one owner. Only the owner writes and only the owner answers for the meaning; the others go to it.

2.4.2 It is not allowed to make a second copy of one and the same: a second file, a second button with the same action, a value in memory taken as true.

2.4.3 An image on the screen, a cache and a value in memory are copies. Whoever holds a copy reads the value from the owner again after its own change.

2.4.4 The check before a change is made by the owner at the moment of the change, not by the holder of a copy.

2.4.5 The prefix of a name names the owner: the key graph.runs_keep belongs to the function of the graph, the method core.status to the kernel.

2.4.6 Signs of breach:

2.5 Extension through a ready place

2.5.1 The base of a part is what the part rests on: the loop of the kernel, the format of a message, the levels of settings, the areas of the workshop. A new possibility must be added to the base as one more element of a ready place: a function — to the register, a key — to the settings schema, a kind of node — to the set of kinds, a window — to the workshop.

2.5.2 Changing the base (a new channel of exchange, a new area of the workshop, a new level of settings) is allowed only by a decision written in the journal of decisions.

2.5.3 An action must be done by the part whose subject it concerns. A node of the graph does not control the platform; a window of the workshop does not change the limits of the kernel.

2.5.4 Signs of breach:

2.6 A part holds no knowledge of other parts

2.6.1 A part must get knowledge of other parts only during work: from the register of functions, from the descriptions the parts give of themselves, and from the answers to calls by the contract.

2.6.2 In the code of a part knowledge of another part of only one sort is allowed — the contract of that part: the names of its methods and events, the formats of its documents, its constants of the contract. This is allowed only if the dependency on that part is declared (2.3.3).

2.6.3 The kernel has no dependencies on any part. So the code of the kernel holds no knowledge of other parts at all: everything the kernel does for the parts is set by the register of functions and the descriptions of functions.

2.6.4 Not allowed in the code of a part:

The owner of a notion is the part in whose description this notion is defined.

2.6.5 If parts need different behaviour, the difference must be expressed by a sign each part declares about itself. Code reads the sign, not the name. Example: the kernel starts the workshop not because it knows the function ui, but because the sign interactive is declared in the description of the function.

2.6.6 A setting of another part is not its contract. If a part needs a value owned by another part, it gets it by a call of a method or by an event of the owner.

2.6.7 Examples of a breach and of the right make-up:

2.6.8 Signs of breach:

2.7 Observability

2.7.1 Everything that affects the result must be named explicitly: the rule of merging inputs, a loop, a retry, a level of a setting, the mark «Keep».

2.7.2 A command changes the state, a query only reads, an event tells of what has already happened. A query that changes anything is a breach.

2.7.3 Each action must leave a record in the journal with identifiers by which the order of events is restored.

2.7.4 A failure of background work (work nobody waits an answer for) must be reported by an event, and if an event cannot be sent — by output into the error stream that the kernel keeps.

2.7.5 Signs of breach:

2.8 Nothing superfluous

2.8.1 It is not allowed to make a layer, a library, a channel, a wrapper or a sign for one case or in advance. A mechanism is allowed if it has two users, or the second user is written in the requirements specification or in the journal of decisions.

2.8.2 A new outside dependency is allowed only with a written reason.

2.8.3 Rule 2.2 does not contradict this: a setting is not a superfluous mechanism, it is the lawful place of a value.

2.8.4 Signs of breach:

2.9 Uniformity

2.9.1 One and the same thing must be named alike and work by one contract in all parts.

2.9.2 Examples: the protocol is one for the kernel and the functions; the look tokens are one for the frame of the workshop and the windows; writing and resetting a setting work alike for any keys.

2.9.3 Signs of breach:

2.10 Self-sufficiency of an element

2.10.1 Everything that makes an element what it is must lie in its folder: code, its description of itself, texts for the person in both languages, its sign, checks, subfolders for what divides further.

2.10.2 A change of an element is made in one folder and touches neither other elements nor the system the element works in.

2.10.3 Adding an element is adding its folder, removing it is removing the folder. The other elements go on working.

2.10.4 Outside the folder only an entry in a ready place is allowed, and only if it cannot be derived from the folder of the element.

2.10.5 The system the elements work in describes its mechanism in the documentation, not each element. What many elements share (the loop that calls them, the contract by which they are spoken to) belongs to the system and is not copied into the elements.

2.10.6 Signs of breach:

2.11 Independence of the platform from the documentation

2.11.1 The documentation describes the platform; the platform does not know of the documentation. References to documents, their sections, numbers of rules and codes of requirements are not allowed in the code of parts, dictionaries, interface texts, messages, journal records, names and descriptions of checks. One thing is allowed: the item «Help» opens the documentation on the site of the platform, ogas.space, as a whole, without a section.

2.11.2 A comment in code must explain in its own words what the code does and why it is made this way. If the explanation rests on a requirement of the documentation, the requirement is told in substance, without a reference to the document.

2.11.3 Development tools (checks in make ci) are allowed to read the documentation to compare code with the described contract. Development tools are not part of the delivery.

2.11.4 The developers' documentation is not part of the delivery; the documentation for people is read on the site of the platform.

2.11.5 Signs of breach:

3 Requirements for the behaviour of the platform toward the person

3.1 Actions only with the person's knowledge

3.1.1 The platform must not do actions the person did not ask for and will not learn of.

3.1.2 Programs and dependencies are installed only by an explicit command of the person, not at a start.

3.1.3 The person's data are deleted only at their direct request or by a rule the person sees and can set up. An example of such a rule is clearing old runs by the setting graph.runs_keep.

3.1.4 Overflow, a break and a refusal must end in a visible error, not in a loss of data.

3.1.5 The platform does not stop and does not throw away unsaved changes without asking the person.

3.1.6 The platform does not send data beyond the computer on its own initiative.

3.1.7 Signs of breach:

3.2 An explicit refusal

3.2.1 If the platform cannot fulfil a request, it must refuse and report the error code, a text for the person, the place of the refusal and a sign whether a retry will help.

3.2.2 The unfamiliar is not read as familiar. A document of a newer version, a path beyond the allowed folder, an unknown format cause a refusal, not an attempt to guess.

3.2.3 A refusal leaves no partly done work: what was written is returned to its former state or explicitly marked as incomplete.

3.2.4 Signs of breach:

3.3 No false promises

3.3.1 The interface and the documentation must not show a possibility or a protection that is not there. There is no sandbox for modules, so the rights of a module are not shown.

3.3.2 Performance and limits are named only by the results of a measurement with the machine and the date named.

3.3.3 The platform does not undo the outside actions of a module (letters, files, requests to the network) and says so plainly.

3.3.4 Signs of breach:

3.4 Clear language of the interface

3.4.1 Everything the person sees must be written in everyday words. A person who can use programs need not know the terms of the platform.

3.4.2 The requirement concerns the workshop, the names and explanations of settings, error messages and the dictionaries of modules.

3.4.3 A term is allowed only in the details and only beside an explanation.

3.4.4 A hint says what will happen, not how it is made inside. An error message says what happened and what to do.

3.4.5 Each text for the person must be in Russian and English.

3.4.6 Command line output is a tool of development and diagnostics; requirements 3.4.1–3.4.5 do not extend to it.

3.4.7 Signs of breach:

3.5 Keeping what is written safe on a failure

3.5.1 A document must be written whole or not at all: the former whole version is kept when writing breaks off.

3.5.2 Interrupted work stays resumable or is explicitly marked as not resumable.

3.5.3 Signs of breach:

4 The order of development

4.1 From the general to the particular

4.1.1 Development goes by levels: purpose and requirements → the make-up of the platform as a whole (The make-up of the platform) → the make-up of the parts (The program: graph and runs — Protection) → contracts and formats (Exchange with the kernel, File formats).

4.1.2 The next level is not discussed or implemented until the previous one is agreed.

4.1.3 A question about particulars that came up while discussing the general is written into the list of open questions with its level named and is considered in its turn.

4.1.4 Implementation is done in the same order: first what the whole rests on, then the particulars.

4.2 Recording decisions

4.2.1 Each decision must be written into the journal of decisions with its reason. A decision without a reason cannot be reviewed on grounds. The journal is kept outside the documentation (5.1.4).

4.2.2 A decision that changes the description of the product is entered at the same time into the document it changes. A record in the journal without a change of the document, and a change of the document without a record in the journal, are a breach.

4.2.3 Decisions about the product (what the platform does for the person) are made by the product owner. Technical decisions within the decisions about the product already made are made by the developer, who writes them with their reason.

4.2.4 A revised decision is not deleted: the former and the new one are written side by side in the section of revised decisions of the journal.

4.3 The documentation takes precedence over code

4.3.1 The documentation sets how it must be; code is brought into line with it.

4.3.2 If code differs from the documentation, the code is fixed. Until it is fixed, the difference is written in the list of nonconformities. After the fix the record is removed.

4.3.3 The documentation is changed only by a decision (4.2). It is not allowed to change the documentation because the code is already made otherwise.

4.4 Open questions

4.4.1 A question without a decision must be written in the list of open questions together with the developer's proposal. It is not allowed to close a question with code on the principle «for now».

4.4.2 A decided question is removed from the list, and the decision is written by 4.2.

4.5 Confirming readiness with a check

4.5.1 Work is called ready only after a check that can be repeated: an automatic check, a run or a measurement.

4.5.2 Each new automatic check is run once on code known to be spoiled to make sure it does not pass. A check that cannot fail does not count as a check.

4.5.3 What is not checked is called not checked in the report and in the list of nonconformities.

4.5.4 A manual check is written down with the build, the machine, the date and the result.

4.5.5 A rule whose keeping a program can check must be checked by a program in make ci.

4.6 The order of working out mechanism and perception

4.6.1 The parts of the platform are of two sorts, and their order of work differs.

4.6.2 Mechanism — the node system, the protocol, the formats of documents, the rules of a run. A mechanism is fully expressed by text and schemes, and an error in it is irreversible: people's documents are already written on disk in the former form. A mechanism is worked out fully before implementation. Working out is finished when a new way of analysis changes neither the code nor the documentation.

4.6.3 Perception — the look of a node on the canvas, the make-up of the pulpit, what the person sees and where they direct an action. Perception cannot be derived by reasoning. It begins with a sketch: drawn, tried, judged on the screen, and only after that the decision is written down.

4.6.4 A part is counted as mechanism if its error cannot be fixed without spoiling what people have already made.

4.6.5 The grounds: what is foreseen is easy to throw away, and what is not foreseen is hard to bring into a developed system. Completeness can be proved only for a closed set, for example for the set of kinds of nodes. An open set, for example the tasks of people, is checked only by going through cases and by use.

4.7 Control questions before adding something new

4.7.1 Before adding a function, a document, a setting, a window, a kind of node, a method or a field of a format the developer answers five questions:

1) who is the owner and who has no right to change it (rule 2.4); 2) which ready place it takes (rule 2.5); 3) which values in it are set up and which texts the person will see (rules 2.2 and 3.4); 4) through which contract other parts interact with it and which dependencies are declared (rules 2.3 and 2.6); 5) whether choosing behaviour by a name arises and which sign will replace it (rule 2.6).

4.7.2 If at least one question has no answer, the code is not written, and the question is written down by 4.4.

5 Requirements for the documentation

5.1 Purpose and make-up

5.1.1 The documentation describes the platform as it is: what it does, how to use it, how it is made and how to extend it. Code is brought into line with it (4.3).

5.1.2 The make-up of the documentation is the map docs/README.md: each document is named on it with a link and whom it is for. A document that is not on the map is not part of the documentation; a new document is entered on the map together with its making.

5.1.3 The documents are laid out by readers: guide/ — for whoever builds programs; reference/ — the reference; sdk/ — for the author of modules and scripts; platform/ and contract/ — for whoever studies how the platform is made.

5.1.4 Decisions with their reasons, open questions, nonconformities of code with the documentation, research and measurements are kept outside the documentation. The documentation retells only what of them has become the make-up of the platform.

5.1.5 The English translation of the documentation lies in docs/en/ with its own map docs/en/README.md. A translated document has the same numbered sections as the Russian one, and they are edited together: make ci compares the sections of the translation with the original, checks its links, and checks its lists of settings, error codes, kinds of nodes and SDK names against the code.

5.2 Content

5.2.1 A document describes only the present platform. Dates, references to decisions and to who made them, stories of how it was before and what will be later are not allowed. The reason «why so» is told in substance, as a property of the make-up.

5.2.2 Each fact is written in one document. Other documents refer to it and do not repeat it.

5.3 Structure

5.3.1 A document begins with the title «# Name» and a short introduction: what the document is about and whom it is for.

5.3.2 Sections, subsections and items are numbered with Arabic digits: «1», «1.1», «1.1.1»; no dot is put after the number. Reference material not needed to understand the main text is put into appendices: «Appendix A».

5.3.3 A table gets a caption above it: «Table 3 — Name»; tables are numbered through the whole document.

5.4 Language and style

5.4.1 The documents are written in plain and exact Russian: one thought — one paragraph, the main thing first, then the details. A word from code is explained in words at its first appearance. The English translation follows the same rule in English.

5.4.2 Requirements for code are worded with «must», «is not allowed», «is allowed» (1.4.1).

5.4.3 Terms are used in the meanings from Terms. One term denotes one notion; a new term is entered there before its first use.

5.4.4 Names from code, formats, methods and keys are written in monospace as they are written in code. Quotation marks are «guillemets»; a dash between words is long, with spaces.

5.5 References

5.5.1 Another document is referred to by its name with a link to the file and the number of the section: «(The program: graph and runs, 12.1)».

5.5.2 Inside a document the reference is to a number: «(see 5.1)», «(table 3)», «(Appendix A)».

5.6 Signs of breach of the requirements for the documentation

5.6.1 Signs of breach:

Appendix A (informative). Applying the rules in the parts

Table A.1 — Examples of applying the rules

Rule The kernel and the functions of the platform Modules The workshop
2.1 Division into components main.rs only starts the part and passes methods on; handling requests, computation and keeping — in their own files a module is one task in its own folder, main.py is the entry point, common code is in sdk/python app.js is the entry point; each window is a folder of its own in host/; the frame is shell.js
2.2 Values and texts outside code limits — in the settings schema of the owner, texts — in its locales/, error codes and formats — in the constants file the schema of the parameters of a node — in the manifest, texts — in the locales/ of the module sizes and colours — the settings ui.*, labels — in dictionaries
2.3 Interaction through the contract a function can be switched off in the register, the others work a module can be removed, a process will get a clear refusal a window can be closed or replaced, the instance works
2.4 A single owner the document of a process is written only by the function of the graph a module owns its files the meaning of actions is the function of the graph's, a window only shows
2.5 Ready place a new function is a folder in functions/ with a description and an entry in functions.json a new module is a folder in modules/ a new window is a folder in host/ and a subsection of a bar
2.6 No knowledge of other parts the kernel chooses behaviour by the sign interactive from the description of the function and by the right process given to it in the register of the instance a module knows only the protocol of modules a window learns the kinds of nodes and their fields from the answers of the function of the graph
2.10 Self-sufficiency of an element a function is the folder functions/<id>/: description, code, settings schema, dictionaries; a kind of node is a folder in the function of the graph: the description of the kind, the step, the check, the words, the sign, checks a module is the folder modules/<id>/: manifest, code, dictionaries, checks a window is a folder in host/: view, state, words, sign, checks
2.11 Independence from the documentation a comment explains the reason in its own words the dictionaries of a module do not refer to documents the texts of a window do not refer to documents
3.1 Actions with the person's knowledge old runs are cleared only by a setting the environment is installed only by a command closing the workshop asks about what is unsaved
3.2 An explicit refusal document_invalid for an unknown format module_environment_conflict with a list of modules an error text for the person instead of silence
3.4 Clear language — the name and description — in the dictionaries of the module labels, hints, errors