Luigit
repositories / termux-janitor

termux-janitor

Interactive cleanup assistant for Termux: transparent, safe, confirmed disk reclamation.

owned by admin

tools/spec-engine/spec/ENGINE.md

Raw
Rendered preview

Specification engine

The engine keeps a repository's requirements, verification obligations, prose fixtures, executable bindings, implementation units, and generated projections synchronized. It enforces relationships. It decides no meaning.

Requirement identifiers here are engine-owned and use the SE- prefix. They are independent of any consuming repository's requirement registry.

Authority

SE-CORE-01. The engine owns relationship mechanics only: identity, revision, polarity, fingerprint, containment, uniqueness, reachability, and freshness. It never asserts that a fixture meaningfully verifies a requirement, or that declared obligations fully express its prose.

SE-CORE-02. The engine contains no product-domain fact. Verification lanes, identifier grammar, registry locations, tool invocation, and projection preambles arrive through the profile module. A fact that both the engine and a consumer need lives in the profile, never in duplicate.

SE-CORE-03. Generated output owns no semantics. Any file the engine writes is reproducible from its owning registries and may be deleted and regenerated at any time.

Relationship graph

SE-GRAPH-01. The graph is:

document#anchor
    owns
requirement@revision
    owns
verification obligation@revision
    ├── realized by implementation unit@revision
    └── claimed by fixture oracle through test specification@revision
                     executed through binding@revision → generated Zig test

SE-GRAPH-02. Fixtures never link to documents and never link to requirements directly. Claims and implementation units meet at obligation revisions, so presentation structure can change without invalidating verification.

SE-GRAPH-03. Every link names a stable identifier and an exact revision. A reference to a superseded revision fails the gate and is resolved by review, never by advancing the number.

Verification lifecycle

SE-LIFE-01. Verification state is derived from artifacts, never declared by an editable flag.

Present Derived state
Prose fixture only specified
Fixture plus one zig tj-test fence instrumented
Instrumented fixture plus current binding bound
Generated test compiled into its declared suite executable
Result for exact revisions executed
Successful result passed

SE-LIFE-02. A prose-only fixture is a valid specified test. Instrumentation is optional; a binding without instrumentation, or instrumentation without a binding, fails.

SE-LIFE-03. A descriptor is not coverage. Passing a claim is evidence for its obligations and never a statement of complete requirement coverage.

Suite evidence records

SE-EVID-01. The build graph writes one bounded, transient record per suite immediately after a fresh, successful run of that suite's generated tests. The record freezes the test-specification, fixture, binding, artifact, toolchain, and option identities of that run. Attribution never rereads changed manifests: every identity enters the record at build time.

SE-EVID-02. Records are untracked build output. Each suite owns at most one record, replaced atomically. A failed, interrupted, cached-only, filtered, empty, or skipped run writes no success record, and the repository's prohibition on skipped tests is unaffected.

SE-EVID-03. The join between records and the current graph is deterministic. An exact identity match yields passed; a suite record without the exact identity yields superseded; no record yields not_executed. A missing record is never a failure verdict and never becomes one through presentation.

SE-EVID-04. Suite evidence records suite execution only. It never equates suite success with requirement acceptance, never covers unregistered work, and never replaces the evidence fields and suite-specific records required by the repository testing document.

Fixtures and instrumentation

SE-FIX-01. A prose fixture owns one scenario: setup, stimulus, required observations, forbidden effects, variations, and limitations. It specializes linked requirements and introduces no competing behavior. It carries a stable identifier and semantic revision.

SE-FIX-02. An executable fixture contains exactly one zig tj-test fenced block under an exact ## Instrumentation heading. Generation places its body verbatim into an ordinary Zig test with the binding module's Fixture in scope. Zig owns the instrumentation language, type checking, error propagation, discovery, execution, and reporting. The engine adds no expression evaluator and no parallel assertion engine.

SE-FIX-03. Fixture methods use given_, when_, then_, and forbid_ prefixes. Phase order is enforced, at least one given_ and exactly one when_ are required, and each then_ or forbid_ call maps uniquely onto a declared oracle present in both the prose and the claim set.

SE-FIX-04. A test specification owns identity, revision, suite, exact fixture revision and fingerprint, production boundary, and the claims mapping each oracle to exact obligation revisions. It never restates fixture prose.

Strict synchronization

SE-SYNC-01. Prose fixtures, fixture binding sources, and implementation sources carry reviewed SHA-256 fingerprints. Any byte change invalidates the reviewed link until the change is classified.

SE-SYNC-02. Updating a fingerprint records that a change was reviewed. It never advances a semantic revision and never constitutes semantic acceptance.

SE-SYNC-03. Every source under the profile's implementation root belongs to exactly one implementation unit. Every fixture implementation under the profile's binding root has exactly one current binding.

SE-SYNC-04. Every executable product test originates from one instrumented prose fixture. Handwritten product and binding sources contain no Zig test declaration. Engine self-tests run only from the engine's own test target and never count as product evidence.

Generation before linking

SE-GEN-01. Prefer generation whenever downstream content is derivable from one authoritative owner. Generated code, tests, projections, manifests, and indexes contain no manually maintained relationship.

SE-GEN-02. Use explicit links only where generation cannot decide: oracle to obligation, and implementation unit to obligation.

SE-GEN-03. Transformations offered by the tool are explicit and on demand. One never chooses a semantic relationship, never advances a semantic revision, and never runs from a read-only gate.

Build integration

SE-BUILD-01. The build graph is derived from the registries. Adding a test specification, a binding, or a suite changes no build file. A consumer's build reads the test and binding registries and creates one generated test root, one module per binding, and one target per suite that has at least one binding.

SE-BUILD-02. Every declared suite is either runnable or absent. A suite with bindings always has a target; a suite without bindings has none. Suites are partitioned into local suites, which run in ordinary gates, and reserved suites, which run only in the continuous-integration gate.

Scaffolds and transformations

SE-SCAF-01. Scaffolds and authoring plans are disposable material written to standard output. They mutate no registry, register no test, and claim no coverage. A generator may create a file that does not exist yet when asked explicitly, and never overwrites one.

SE-SCAF-02. An unfinished generated implementation fails compilation through @compileError. It never passes, skips, or reports coverage.

SE-SCAF-03. Gates validate before answering. Generators, transformations, and reports do not, because their purpose is to resolve an inconsistent model. A command that repairs a condition never refuses to run because of that condition.

SE-SCAF-04. Fingerprint synchronization is a transformation, not a decision. It reports every digest it changes and restates that a semantic change still needs a revision increment and link migration.

Reporting

SE-REP-01. Status is derived, never stored. It distinguishes obligations that are unclaimed, claimed but unbound, and executable, and separately reports whether an implementation unit realizes them.

SE-REP-02. Reports state evidence, never sufficiency. An executable obligation means a generated test exercises the claim, not that the requirement is completely covered.

SE-REP-03. Status derives requirement progress as done, partial, or missing from the obligation graph, reports the first incomplete requirement as next, and exposes the same data in human-readable and JSON output. Structural diagnostics include status as an inspection reference when graph progress can help resolve the failure.

Diagnostics

Diagnostics are the engine's only instruction channel. See DIAGNOSTICS.md.

SE-DIAG-01. Every failure names a stable code, the kind of disputed fact, its canonical owner, the commands that inspect it and its dependents, the permitted resolution, and the command that verifies the fix.

SE-DIAG-02. No consuming repository is expected to document engine usage. If an author needs a procedure that is not derivable from a failure message or a generator, the diagnostic is defective and is fixed in the engine rather than described in prose.

# Specification engine

The engine keeps a repository's requirements, verification obligations, prose fixtures, executable
bindings, implementation units, and generated projections synchronized. It enforces relationships.
It decides no meaning.

Requirement identifiers here are engine-owned and use the `SE-` prefix. They are independent of
any consuming repository's requirement registry.

## Authority

**SE-CORE-01.** The engine owns relationship mechanics only: identity, revision, polarity,
fingerprint, containment, uniqueness, reachability, and freshness. It never asserts that a fixture
meaningfully verifies a requirement, or that declared obligations fully express its prose.

**SE-CORE-02.** The engine contains no product-domain fact. Verification lanes, identifier grammar,
registry locations, tool invocation, and projection preambles arrive through the `profile` module.
A fact that both the engine and a consumer need lives in the profile, never in duplicate.

**SE-CORE-03.** Generated output owns no semantics. Any file the engine writes is reproducible from
its owning registries and may be deleted and regenerated at any time.

## Relationship graph

**SE-GRAPH-01.** The graph is:

```text
document#anchor
    owns
requirement@revision
    owns
verification obligation@revision
    ├── realized by implementation unit@revision
    └── claimed by fixture oracle through test specification@revision
                     executed through binding@revision → generated Zig test
```

**SE-GRAPH-02.** Fixtures never link to documents and never link to requirements directly. Claims
and implementation units meet at obligation revisions, so presentation structure can change without
invalidating verification.

**SE-GRAPH-03.** Every link names a stable identifier and an exact revision. A reference to a
superseded revision fails the gate and is resolved by review, never by advancing the number.

## Verification lifecycle

**SE-LIFE-01.** Verification state is derived from artifacts, never declared by an editable flag.

| Present | Derived state |
|---|---|
| Prose fixture only | specified |
| Fixture plus one `zig tj-test` fence | instrumented |
| Instrumented fixture plus current binding | bound |
| Generated test compiled into its declared suite | executable |
| Result for exact revisions | executed |
| Successful result | passed |

**SE-LIFE-02.** A prose-only fixture is a valid specified test. Instrumentation is optional;
a binding without instrumentation, or instrumentation without a binding, fails.

**SE-LIFE-03.** A descriptor is not coverage. Passing a claim is evidence for its obligations and
never a statement of complete requirement coverage.

## Suite evidence records

**SE-EVID-01.** The build graph writes one bounded, transient record per suite immediately after a
fresh, successful run of that suite's generated tests. The record freezes the test-specification,
fixture, binding, artifact, toolchain, and option identities of that run. Attribution never rereads
changed manifests: every identity enters the record at build time.

**SE-EVID-02.** Records are untracked build output. Each suite owns at most one record, replaced
atomically. A failed, interrupted, cached-only, filtered, empty, or skipped run writes no success
record, and the repository's prohibition on skipped tests is unaffected.

**SE-EVID-03.** The join between records and the current graph is deterministic. An exact identity
match yields `passed`; a suite record without the exact identity yields `superseded`; no record
yields `not_executed`. A missing record is never a failure verdict and never becomes one through
presentation.

**SE-EVID-04.** Suite evidence records suite execution only. It never equates suite success with
requirement acceptance, never covers unregistered work, and never replaces the evidence fields and
suite-specific records required by the repository testing document.

## Fixtures and instrumentation

**SE-FIX-01.** A prose fixture owns one scenario: setup, stimulus, required observations, forbidden
effects, variations, and limitations. It specializes linked requirements and introduces no competing
behavior. It carries a stable identifier and semantic revision.

**SE-FIX-02.** An executable fixture contains exactly one `zig tj-test` fenced block under an
exact `## Instrumentation` heading. Generation places its body verbatim into an ordinary Zig
`test` with the binding module's `Fixture` in scope. Zig owns the instrumentation language, type
checking, error propagation, discovery, execution, and reporting. The engine adds no expression
evaluator and no parallel assertion engine.

**SE-FIX-03.** Fixture methods use `given_`, `when_`, `then_`, and `forbid_` prefixes. Phase order
is enforced, at least one `given_` and exactly one `when_` are required, and each `then_` or
`forbid_` call maps uniquely onto a declared oracle present in both the prose and the claim set.

**SE-FIX-04.** A test specification owns identity, revision, suite, exact fixture revision and
fingerprint, production boundary, and the claims mapping each oracle to exact obligation revisions.
It never restates fixture prose.

## Strict synchronization

**SE-SYNC-01.** Prose fixtures, fixture binding sources, and implementation sources carry reviewed
SHA-256 fingerprints. Any byte change invalidates the reviewed link until the change is classified.

**SE-SYNC-02.** Updating a fingerprint records that a change was reviewed. It never advances a
semantic revision and never constitutes semantic acceptance.

**SE-SYNC-03.** Every source under the profile's implementation root belongs to exactly one
implementation unit. Every fixture implementation under the profile's binding root has exactly one
current binding.

**SE-SYNC-04.** Every executable product test originates from one instrumented prose fixture.
Handwritten product and binding sources contain no Zig `test` declaration. Engine self-tests run
only from the engine's own test target and never count as product evidence.

## Generation before linking

**SE-GEN-01.** Prefer generation whenever downstream content is derivable from one authoritative
owner. Generated code, tests, projections, manifests, and indexes contain no manually maintained
relationship.

**SE-GEN-02.** Use explicit links only where generation cannot decide: oracle to obligation, and
implementation unit to obligation.

**SE-GEN-03.** Transformations offered by the tool are explicit and on demand. One never chooses a
semantic relationship, never advances a semantic revision, and never runs from a read-only gate.

## Build integration

**SE-BUILD-01.** The build graph is derived from the registries. Adding a test specification, a
binding, or a suite changes no build file. A consumer's build reads the test and binding registries
and creates one generated test root, one module per binding, and one target per suite that has at
least one binding.

**SE-BUILD-02.** Every declared suite is either runnable or absent. A suite with bindings always has
a target; a suite without bindings has none. Suites are partitioned into local suites, which run in
ordinary gates, and reserved suites, which run only in the continuous-integration gate.

## Scaffolds and transformations

**SE-SCAF-01.** Scaffolds and authoring plans are disposable material written to standard output.
They mutate no registry, register no test, and claim no coverage. A generator may create a file that
does not exist yet when asked explicitly, and never overwrites one.

**SE-SCAF-02.** An unfinished generated implementation fails compilation through `@compileError`. It
never passes, skips, or reports coverage.

**SE-SCAF-03.** Gates validate before answering. Generators, transformations, and reports do not,
because their purpose is to resolve an inconsistent model. A command that repairs a condition never
refuses to run because of that condition.

**SE-SCAF-04.** Fingerprint synchronization is a transformation, not a decision. It reports every
digest it changes and restates that a semantic change still needs a revision increment and link
migration.

## Reporting

**SE-REP-01.** Status is derived, never stored. It distinguishes obligations that are unclaimed,
claimed but unbound, and executable, and separately reports whether an implementation unit realizes
them.

**SE-REP-02.** Reports state evidence, never sufficiency. An executable obligation means a generated
test exercises the claim, not that the requirement is completely covered.

**SE-REP-03.** Status derives requirement progress as `done`, `partial`, or `missing` from the
obligation graph, reports the first incomplete requirement as `next`, and exposes the same data in
human-readable and JSON output. Structural diagnostics include `status` as an inspection reference
when graph progress can help resolve the failure.

## Diagnostics

Diagnostics are the engine's only instruction channel. See [`DIAGNOSTICS.md`](DIAGNOSTICS.md).

**SE-DIAG-01.** Every failure names a stable code, the kind of disputed fact, its canonical owner,
the commands that inspect it and its dependents, the permitted resolution, and the command that
verifies the fix.

**SE-DIAG-02.** No consuming repository is expected to document engine usage. If an author needs a
procedure that is not derivable from a failure message or a generator, the diagnostic is defective
and is fixed in the engine rather than described in prose.