Projects
A Sec project is the complete source tree governed by one project manifest:
.sec/sec.toml
The project defines the buildable products, reusable platform variants, compiler defaults, compile-time parameters, output rules and project-wide tooling settings for that source tree.
Source modules are discovered from the directory tree and imports. They do not need to be repeated as a manually maintained module list in the manifest.
.sec/sec.toml manifest and any number of logical build targets inside that project.
Project Terminology
| Term | Meaning |
|---|---|
| Project | The complete source tree governed by one .sec/sec.toml |
| Module | One source directory and its shared Sec namespace |
| Target | One logical buildable product |
| Variant | One concrete platform/build configuration for a target |
| Artifact | A file produced by one target variant |
| Compilation plan | The fully resolved target + variant build configuration used by the compiler |
These concepts are deliberately separate. A module is not a project, and a target is not an operating-system/architecture pair.
Project Boundary
The directory containing .sec/sec.toml is the project root.
shop/
.sec/
sec.toml
cmd/
internal/
domain/
bin/
The manifest governs the complete source tree below that root.
Applications, command-line tools, libraries, firmware images and other independently buildable products are represented as targets inside the same project.
Sec does not use a separate manifest for every source module.
The Project Manifest
The canonical project manifest is:
.sec/sec.toml
It describes project-level build information such as:
- project identity;
- default build behavior;
- profiles;
- reusable variants;
- logical targets;
- compiler options;
- compile-time parameters;
- analysis/tooling settings;
- build-counter configuration;
- dependencies when the dependency model is implemented.
One Manifest per Project
A project contains exactly one .sec/sec.toml.
Nested Sec projects are not supported.
This is invalid:
project/
.sec/sec.toml
server/
.sec/sec.toml
worker/
.sec/sec.toml
server and worker should instead be represented as targets
in the root project manifest.
The single-manifest rule gives project-wide tooling one coherent view of:
- imports and dependency resolution;
- target and variant selection;
- formatting;
- diagnostics;
- ownership and whole-project analysis;
- call graphs;
- stack and allocation analysis;
- build caching;
- platform selection.
Project Discovery
Project-aware tools search the current directory and parent directories for:
.sec/sec.toml
The nearest valid containing project manifest defines the active project.
This lets commands such as sec init run from a directory inside the
project without creating a second nested project.
Source Discovery
Ordinary source modules are discovered through directory structure and import reachability.
A target names its entry module:
[target.shop]
kind = "command"
source = "cmd/shop"
The complete source graph is then derived by following imports.
The manifest does not require a list such as:
# Not required:
modules = [
"domain/orders",
"domain/products",
"storage/database",
]
Module discovery remains part of the module/import model described in the previous chapter.
Project-Root Source Files
Sec source files may exist directly in the project root. This is useful for small projects and root libraries.
codec/
.sec/
sec.toml
codec.sec
encoder.sec
internal/
parser/
parser.sec
Root-level .sec files form one root module.
For a root library module, the expected module name is:
project.modulewhen explicitly declared in the manifest;- otherwise
project.namewhen the project name is a valid Sec identifier.
[project]
name = "codec"
Root files then use:
module codec
If the project name is not a valid Sec identifier, declare the source module name explicitly:
[project]
name = "inventory-service"
module = "inventory"
Root source files then declare:
module inventory
A minimal command project may instead use the project root itself as an entry module:
module main
with:
[target.app]
kind = "command"
source = "."
One directory cannot simultaneously be both module main and a differently
named root library module.
Reserved and Recognized Directories
The project-root names reserved by Sec are:
cmd
bin
.sec
internal is recognized and carries mandatory access semantics when used,
but using it is optional.
Other organizational directory names normally have no special language meaning.
cmd
cmd is the canonical source root for executable and firmware entry targets.
cmd/
shop/
main.sec
worker/
main.sec
Rules:
.secfiles may not exist directly incmd/;- each target is placed in a child directory;
- a command or firmware entry module normally declares
module main; - reusable code should live outside the entry module;
- entry modules should primarily configure and connect reusable modules.
This is invalid:
cmd/shared.sec
bin
bin is reserved for generated build output.
Rules:
binis never a source module;- imports from
bin/...are invalid; .secsource belowbinis invalid project source;sec cleanmay remove compiler-owned output belowbin;- unknown user files must not be removed merely because they happen to be below
binunless compiler ownership is recorded.
.sec
.sec is compiler and project metadata storage.
.sec/
sec.toml
state/
cache/
Source modules must not be declared below .sec.
Mutable compiler-owned state belongs below this directory rather than being written back into source files or the declarative manifest unless the manifest itself is intentionally edited.
internal
internal is an optional but recognized access-control marker.
Its restrictions are mandatory whenever the path segment is used.
internal/
storage/
storage.sec
The source module still declares:
module storage
.sec files may not be placed directly in an internal marker directory:
internal/helper.sec // invalid
Use a child module directory:
internal/
helper/
helper.sec
Import accessibility follows the subtree rule documented in Modules and Imports.
Ordinary Organizational Directories
Names such as these have no special language semantics:
modules
domain
application
app
services
features
components
adapters
infrastructure
Projects may use them freely.
In particular, a directory named modules is not required and is not
treated specially by the compiler.
Project Identity
The manifest's [project] section defines project identity information.
A simple root-library project may use:
[project]
name = "codec"
When the project name cannot itself be a Sec module identifier, provide an explicit root module name:
[project]
name = "inventory-service"
module = "inventory"
Project identity is stable project metadata.
Project tools such as sec init must preserve the existing project identity,
project UUID and project name rather than silently replacing them.
The exact project-identity fields supported by the manifest are compiler-versioned. Unknown required fields must not be invented by tools.
Analysis Settings
Project-wide analysis/tooling settings live under:
[analysis]
The current closure-analysis setting includes:
[analysis]
lsp_depth = "interactive"
Such settings control tooling resource use and optional precision.
They do not redefine language semantics and do not disable safety analysis required for program correctness.
Targets
A target is one logical buildable product.
Targets are declared under:
[target.<name>]
Example:
[target.shop]
kind = "command"
source = "cmd/shop"
artifact = "shop"
variants = [
"linux-amd64",
"macos-arm64",
"windows-amd64",
]
A target owns:
- logical product identity;
- entry module;
- target kind;
- artifact base name;
- selected variants;
- target-specific compiler options;
- target-specific compile-time parameters;
- build-counter behavior.
Target Kinds
The initial target kinds are:
command
library
firmware
test
The target kind describes what logical product is being built.
The test target kind is for an explicitly buildable test-oriented target
or artifact.
Ordinary source-level tests and sec test do not require a manifest
test target.
Target Source
The target source identifies the entry module.
[target.worker]
kind = "command"
source = "cmd/worker"
The full source graph is discovered by following imports from that entry.
The source path and target kind do not vary by platform variant.
If two outputs require different entry modules or represent different logical products, declare separate targets.
Test Compilation
sec test creates a dedicated TestCompilationPlan.
It is not implemented by taking a production build and casually appending test files.
Production builds exclude:
*_test.secfiles;- the project-root
tests/tree.
A test compilation may include:
- ordinary production sources;
- same-directory
*_test.secwhite-box tests; tests/integration/black-box modules;- test-only dependencies;
- compiler-known testing support;
- generated harness roots;
- execution metadata.
Modules below tests/ follow ordinary module/import rules and receive no
special friend visibility.
Production code may not depend on test-only declarations.
Variants
A variant is a reusable concrete platform/build configuration.
Variants are declared under:
[variant.<name>]
Examples:
[variant.linux-amd64]
os = "linux"
arch = "amd64"
abi = "gnu"
[variant.macos-arm64]
os = "macos"
arch = "arm64"
[variant.windows-amd64]
os = "windows"
arch = "amd64"
abi = "msvc"
A target chooses which declared variants belong to that logical product.
Canonical Operating-System Names
Initial canonical operating-system names include:
linux
windows
macos
freebsd
netbsd
baremetal
freertos
The source/project name for Apple's desktop operating system is macos,
not darwin.
The compiler may still lower that target to an internal Darwin target triple.
Canonical Architecture Names
Initial canonical architecture names include:
amd64
arm64
arm32
riscv32
Architecture names belong to the Sec project/target model rather than being arbitrary host-toolchain strings.
Additional Variant Options
A variant may also define values such as:
cpu
features
abi
toolchain
profile
This allows one reusable variant to describe details beyond just OS and architecture.
CPU selection and feature selection become part of the concrete compilation plan and build/cache identity when they affect generated output.
Project Manifests Express Toolchain Intent
The manifest may identify a toolchain class or intent.
Machine-specific SDK paths, compiler installation paths and local filesystem locations belong in user or CI configuration rather than the portable project manifest.
This keeps the repository reproducible across developer machines and build agents.
sec build
Build a target with:
sec build shop
By default this builds every variant configured for target shop.
If the target declares:
variants = [
"linux-amd64",
"macos-arm64",
"windows-amd64",
]
one build invocation attempts all three configured outputs.
Build Filters
A build invocation can select a subset of already configured variants:
sec build shop --variant linux-amd64
sec build shop --os linux
sec build shop --arch amd64
sec build shop --profile debug
Filters select configured variants.
Command-line overrides affect only that invocation and do not rewrite the manifest.
Multi-Variant Build Results
By default the compiler should attempt every selected variant and report an aggregate result.
A --fail-fast option may stop the build after the first failed variant.
The complete command exits unsuccessfully when any requested variant fails.
Diagnostics should identify which target/variant failed:
error[shop/windows-amd64]: platform operation OpenFile is unavailable
Compilation Plans
Every selected target + variant pair produces one concrete compilation plan.
Conceptually:
CompilationPlan {
Project
Target
Variant
SourceGraph
OS
Architecture
ABI
CPU
CPUFeatures
Profile
CompilerOptions
CompileTimeParameters
BuildNumber
OutputDirectory
LinkConfiguration
}
The compilation plan is the resolved immutable build description consumed by later semantic, lowering and linking stages.
Target-Specific Lowering
The compiler should reuse target-independent parsing and semantic work when safe.
Target-dependent selection and semantic completion must happen before target-specific assumptions are frozen into lowering.
Target-specific concerns include:
- pointer width;
- alignment;
- data layout;
- ABI;
- calling convention;
- symbol naming;
- object format;
- platform imports;
- syscalls;
- linker behavior;
- CPU instructions and feature availability.
The preferred pipeline is conceptually:
Source
-> AST
-> target-independent semantic representation where possible
-> variant-specific semantic completion and source selection
-> MLIR/LLVM lowering
-> target object format
-> final artifact
Project Build Options
Compiler behavior may be configured under project build settings:
[build]
backend = "mlir"
profile = "release"
warnings = "default"
bounds_checks = true
overflow_checks = true
Compiler options may include categories such as:
- backend;
- optimization level;
- debug information;
- stripping;
- LTO;
- bounds checks;
- overflow checks;
- warning level;
- warnings as errors;
- recursion policy;
- allocation policy;
- stack limit;
- minimum OS or kernel version;
- CPU features.
The exact option set is compiler-versioned. Unknown compiler options are errors unless a manifest extension mechanism explicitly permits them.
Profiles
Profiles group reusable compiler settings:
[profile.release]
optimization = "speed"
debug = "line"
strip = true
[profile.debug]
optimization = "none"
debug = "full"
strip = false
A target or variant can select or override the applicable profile according to the configuration precedence rules.
Profiles are build configuration. They do not create a second source-language semantic model.
Compile-Time Parameters
Compile-time parameters are typed program values supplied by build configuration.
[parameters]
telemetry = false
maximum_connections = 1000
product_name = "Shop"
They are not:
- compiler options;
- C-style textual macros;
- arbitrary token substitution.
The exact Sec source syntax used to access compile-time parameters is defined separately.
Compile-Time Parameter Overrides
Target-specific override:
[target.shop.parameters]
maximum_connections = 2000
Variant-specific override:
[variant.windows-amd64.parameters]
native_service = true
Target + variant-specific override:
[target.shop.variant.windows-amd64.parameters]
service_name = "ShopService"
A parameter's type is derived from its original declaration. Every override must preserve that type.
This is invalid:
[parameters]
maximum_connections = 1000
[target.shop.parameters]
maximum_connections = "many"
Compile-Time Parameters Are Not for Secrets
Compile-time parameters may become visible in:
- generated machine code;
- IR;
- object files;
- debug information;
- build caches.
Passwords, tokens, private keys and similar secrets belong in runtime configuration or another appropriate secret-management system.
Configuration Precedence
Settings merge from least specific to most specific:
- compiler defaults;
- project build settings;
- selected profile;
- reusable variant settings;
- target settings;
- target-specific variant settings;
- command-line overrides.
A more specific value overrides a less specific value only when the setting type and option semantics permit the override.
Command-line overrides never modify sec.toml.
Build Output
The default output layout is:
bin/<target>/<variant>/<profile>/<artifact>
Example:
bin/
shop/
linux-amd64/
release/
shop
macos-arm64/
release/
shop
windows-amd64/
release/
shop.exe
Platform-appropriate filename extensions are applied by the compiler.
Output separation prevents one variant from overwriting another variant's artifact.
Artifacts
An artifact is a file produced by one target variant.
Examples include:
- executables;
- static libraries;
- shared libraries;
- object files;
- MLIR files;
- LLVM IR files;
- debug-information files.
A target may define its artifact base name:
[target.shop]
artifact = "shop-server"
Automatic Build Counter
A target may enable an automatic build counter:
[target.shop.build_counter]
enabled = true
scope = "target"
The default scope is target.
A project-wide scope may be configured as:
scope = "project"
Per-target scope is recommended.
One logical target build consumes at most one build number, even when several variants are built together.
shop build 143
linux-amd64
macos-arm64
windows-amd64
All successful artifacts from that logical invocation receive the same build number.
Build-Number Commit Rule
The next build number is reserved for the invocation but is committed only if every requested variant succeeds.
If any requested variant fails:
- the candidate build number is not committed;
- the stored counter remains unchanged;
- the next attempt may reuse the same candidate number.
A filtered build is still a real logical build and consumes one build number on success.
Build-Counter State
The manifest defines counter behavior.
The mutable counter value is not written back into sec.toml.
Compiler-owned local state lives under:
.sec/state/build-counters.toml
Example:
[counter.shop]
value = 142
Local counter state should normally be excluded from version control when local counters are used.
Parallel Builds and Counter Safety
Build-counter updates must remain correct under parallel builds.
The implementation must conceptually:
- lock the relevant counter;
- read the current committed value;
- reserve the next candidate value;
- build the selected variants;
- atomically commit the value only after complete success;
- release the lock.
State files must be updated atomically. A partially written build-counter file is not acceptable.
Explicit Build Numbers
CI or release tooling may provide a build number explicitly:
sec build shop --build-number 2841
An explicit build number:
- is validated;
- is used by every selected variant;
- does not automatically advance the local counter;
- participates in artifact and cache identity.
The initial model requires local state plus explicit CLI build numbers. Additional build-number providers may be added later.
Typed Build Metadata
The compiler should expose typed compile-time build metadata.
Conceptual values include:
build number
project version
target name
variant name
operating system
architecture
profile
source revision when available
dirty-source status when available
The exact Sec source namespace and syntax are defined separately.
Build metadata is typed data, not textual macro substitution.
Project version and build number are separate:
project version: 1.4.0
build number: 143
combined label: 1.4.0+143
The automatic build counter does not modify semantic versioning.
Timestamps Are Not Embedded by Default
Current time is not automatically embedded into every build.
Automatic timestamps reduce reproducibility and depend on local clock state.
Timestamp embedding may be added through an explicit future option rather than being an unavoidable build side effect.
Reproducible Builds
An explicit build number may participate in reproducing a previous build configuration.
Whenever the build number is embedded in an artifact, it is part of compilation/cache identity.
Build Cache Identity
A variant cache key must include every input that may affect generated output.
At minimum this includes:
- compiler version;
- project identity;
- target identity;
- variant identity;
- operating system;
- architecture;
- ABI;
- CPU and features;
- selected profile;
- compiler options;
- compile-time parameters;
- build number when embedded;
- source hashes;
- dependency hashes;
- selected platform-module hashes;
- target directives.
An artifact from one variant must never be reused as though it were an artifact for an incompatible variant.
Native Libraries and Link Metadata Belong to the Build Plan
Native libraries, object files, import libraries, frameworks and search paths are project/package/build metadata resolved into the active compilation plan.
FFI declarations define symbol and ABI semantics.
They do not repeat linker dependency metadata through per-function
@library annotations.
This keeps foreign symbol declarations separate from target-specific linking policy.
sec init
sec init creates or extends a project safely.
Its required behavior is:
- additive;
- idempotent;
- conflict-aware;
- transactional;
- non-destructive.
It must never:
- overwrite an existing user file;
- replace an existing manifest;
- create a nested manifest inside an existing Sec project.
Creating a New Project
When no containing project exists:
sec init
creates a new project in the selected directory.
A normal application profile creates at least:
.sec/sec.toml
cmd/<project-name>/main.sec
bin/
internal/
internal is a recommended initial structure, not a requirement that all
projects use that architecture.
A minimal profile may instead create:
.sec/sec.toml
main.sec
with a project-root command target.
Running sec init in an Existing Project
When the upward project search finds an existing manifest:
sec init
validates and safely extends that project rather than creating another project.
When the existing project is already complete for the requested operation, the command succeeds without changes.
Being already initialized is not itself an error.
Adding Modules
Create a normal source module with:
sec init module domain/orders
This creates:
domain/orders/orders.sec
containing:
module orders
A normal source module is not added to the manifest unless it is independently declared as a build target.
An internal module may be created with:
sec init module internal/storage
which creates:
internal/storage/storage.sec
containing:
module storage
Adding a Command Target
Create a command target with:
sec init command worker
This creates:
cmd/worker/main.sec
with an entry module such as:
module main
fn main() int {
return 0
}
and extends the manifest additively:
[target.worker]
kind = "command"
source = "cmd/worker"
artifact = "worker"
The target may inherit the project's default variant set.
Adding Other Target Kinds
Initial forms may include:
sec init library protocol
sec init firmware controller
sec init test integration
Each command creates only the source structure and manifest entry appropriate for that target kind.
It must not create unrelated boilerplate or rewrite existing user structure.
Initialization Is Idempotent
Running the same operation repeatedly must not duplicate files or manifest sections:
sec init command worker
sec init command worker
The second invocation is a successful no-op when the existing target is compatible.
Existing Manifest Content Must Be Preserved
When .sec/sec.toml already exists, sec init must:
- parse and validate it;
- preserve project identity;
- preserve project UUID;
- preserve project name;
- preserve comments;
- preserve unknown sections;
- preserve user ordering and formatting when practical;
- add only requested missing sections or keys;
- reject incompatible existing declarations.
Project tools must not deserialize and rewrite the complete TOML document in a way that destroys comments or user formatting.
Syntax-aware edits or precise source patches are the preferred model.
Existing Files Are Never Silently Replaced
Initialization follows this policy:
| Existing state | Behavior |
|---|---|
| File missing | Create it |
| Generated file already identical | No-op |
| Compatible user file exists | Preserve it |
| Conflicting user file exists | Report an error and change nothing |
Example:
error: cmd/worker/main.sec already exists but does not define a valid command entry module
no files were changed
sec init Is Transactional
Before writing anything, the command must:
- discover the project;
- read and validate the manifest;
- inspect existing files;
- calculate the complete change plan;
- detect every known conflict.
If any planned operation conflicts, no operation is applied.
The tool must not create several files and directories and only then discover a later conflict that leaves the project half-modified.
Dry Run
Initialization should support:
sec init --dry-run
and equivalent dry-run behavior for initialization subcommands.
Example output:
Planned changes:
create cmd/worker/
create cmd/worker/main.sec
add [target.worker] to .sec/sec.toml
No existing files will be overwritten.
Dry run computes the same conflict-aware change plan without applying it.
Project Architecture Is Not Prescribed
Sec does not require one application architecture.
A reasonable application layout might be:
cmd/
shop/
main.sec
internal/
domain/
application/
adapters/
A library might instead use:
publicmodule/
internal/
implementation/
The compiler should not infer business meaning from directory names such as
domain, application or adapters.
The general recommendation is:
Organize modules by responsibility and reason for change.
Directory names such as utils, helpers, common,
misc and shared may attract mentor-style advice when they
accumulate unrelated responsibilities, but that is not a language error.
Compiler and Project Validation
Project tooling validates at least:
- exactly one project manifest exists;
- no nested project manifest exists;
- source-directory module names are consistent;
- normal module names match the source-directory component;
- root-module declarations match manifest-defined root-module rules;
- dotted module declarations are rejected;
internalis not used as a module name;- internal import visibility is enforced;
- reserved directories are used correctly;
- source files do not exist directly in
cmd,binor aninternalmarker directory; - target names are unique;
- variant names are unique;
- target source paths exist;
- referenced variants exist;
- target and variant settings are compatible;
- compiler options are known and valid;
- compile-time parameter override types match;
- output paths do not collide;
- build-counter configuration is valid;
- counter state updates are atomic;
sec initchanges are conflict-free before application.
Diagnostics
Project diagnostics should explain:
- the violated project rule;
- the relevant path or manifest section;
- the expected structure or value;
- a safe corrective action.
Nested project
nested Sec project manifest is not allowed
project manifest:
project/.sec/sec.toml
nested manifest:
project/server/.sec/sec.toml
help: declare server as a target in the root project manifest
Reserved source directory
Sec source files may not be placed directly in reserved directory `cmd`
help: create a target directory such as `cmd/server`
help: move reusable code to a normal module
Parameter type mismatch
compile-time parameter `maximum_connections` has inconsistent types
project value: int
target value: string
Variant-specific build error
error[shop/windows-amd64]: platform operation OpenFile is unavailable
Best Practices
- Keep one
.sec/sec.tomlat the project root. - Represent applications, tools, libraries and firmware images as targets rather than nested projects.
- Let imports discover ordinary modules; do not mirror the entire source tree in the manifest.
- Keep reusable code out of
cmd/<target>entry modules. - Use reusable variants for recurring platform configurations.
- Use target + variant combinations to generate multiple platform outputs from one logical product.
- Keep machine-specific SDK paths out of the portable manifest.
- Keep compile-time program parameters separate from compiler options.
- Never put secrets in compile-time parameters.
- Use explicit build numbers in CI/release workflows when reproducibility matters.
- Keep generated artifacts below
binand compiler-owned mutable state below.sec. - Use
sec init --dry-runwhen reviewing structural changes to an existing project. - Organize source modules by responsibility rather than forcing one prescribed application architecture.
Summary
- A Sec project is the complete source tree governed by one
.sec/sec.toml. - Nested Sec projects are not supported.
- Applications, tools, libraries and firmware products inside one project are represented as targets.
- A module is a source namespace; a project is the build/configuration boundary.
- A target is one logical buildable product.
- A variant is one concrete platform/build configuration for a target.
- An artifact is one file produced by a target variant.
- Ordinary source modules are discovered through directories and imports and do not require manifest entries.
- The target
sourceidentifies the entry module; imports determine the remaining source graph. - Project-root
.secsource files are allowed. - A root library module uses
project.modulewhen provided, otherwise a validproject.name. - A minimal root command target may use
module mainwithsource = ".". cmd,binand.secare reserved project-root directories.cmdcontains child entry-target modules and cannot contain direct.secsource files.binis generated output and is never a source/import root..secstores the manifest and compiler-owned project state/cache.internalis optional but carries mandatory access semantics when present.- Ordinary organizational names such as
domain,servicesandmoduleshave no special language semantics. - Project tools preserve existing project identity, UUID, name, comments and compatible manifest content.
- Project-wide analysis settings live under
[analysis]. lsp_depthcontrols tooling budget/precision and does not change language safety semantics.- Targets are declared with
[target.<name>]. - Initial target kinds are
command,library,firmwareandtest. - The target source and target kind do not change per platform variant.
- Different entry modules or different logical products require different targets.
sec testuses a dedicatedTestCompilationPlan.- Production builds exclude
*_test.secand the project-roottests/tree. - Variants are declared with
[variant.<name>]. - Canonical OS names include
linux,windows,macos,freebsd,netbsd,baremetalandfreertos. - The Sec project name for macOS is
macos, notdarwin. - Canonical architecture names include
amd64,arm64,arm32andriscv32. - Variants may additionally specify CPU, feature, ABI, toolchain and profile intent.
- Machine-specific SDK/toolchain paths belong in user or CI configuration rather than the portable project manifest.
sec build <target>builds every configured variant for that target by default.- Build filters select declared variants and do not create undeclared variants.
- By default all selected variants are attempted;
--fail-fastmay stop on the first failure. - The build command fails if any requested variant fails.
- Every target + variant pair produces one concrete
CompilationPlan. - Target-independent semantic work should be reused when safe.
- Target-dependent layout, ABI, platform source and lowering are completed per variant.
- Compiler options and compile-time program parameters are separate concepts.
- Unknown compiler options are errors unless an explicit extension mechanism permits them.
- Profiles group reusable compiler settings.
- Compile-time parameters are typed values, not textual preprocessor macros.
- Target, variant and target+variant parameter overrides must preserve the original parameter type.
- Compile-time parameters must not contain secrets.
- Configuration precedence runs from compiler defaults through increasingly specific project/variant/target settings to command-line overrides.
- Command-line overrides do not rewrite the manifest.
- Default artifacts live under
bin/<target>/<variant>/<profile>/<artifact>. - Different variants must never overwrite one another's output.
- A target may enable an automatic build counter.
- One logical multi-variant build receives one build number.
- A failed multi-variant build does not commit the candidate build number.
- Mutable build-counter state is stored outside
sec.tomlunder.sec/state/. - Parallel build-counter updates must be locked and atomically committed.
- An explicit
--build-numberapplies to every selected variant and does not automatically advance the local counter. - Build metadata is typed data, not macro substitution.
- Project version and build number are distinct values.
- Current time is not automatically embedded into builds.
- A reproducible build must not silently allocate a new automatic build number.
- Build cache identity includes every input that can affect generated output.
- Artifacts from incompatible variants must never share cache identity.
- Native linker dependencies are build-plan metadata rather than per-FFI-function
@libraryannotations. sec initis additive, idempotent, conflict-aware, transactional and non-destructive.sec initsearches upward for an existing project before creating anything.- Running
sec initinside an existing project extends or validates that project rather than creating a nested one. sec init module pathcreates a normal module without adding it to the manifest unless it is also a target.sec init command namecreates an entry module and adds the corresponding target manifest section.- Library, firmware and test target initialization use target-kind-specific structures.
- Repeated compatible init commands are successful no-ops.
- Existing user files are never silently overwritten.
- A conflicting init plan changes nothing.
- Manifest edits preserve comments and compatible user formatting when practical.
sec init --dry-runreports the complete planned change set without writing it.- Sec does not require one application architecture.
- The general architecture recommendation is to organize modules by responsibility and reason for change.