Luigit
repositories / termux-janitor

termux-janitor

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

owned by admin

tools/janitor/profile.zig

Raw
// Repository profile consumed by the generic specification engine.
//
// The engine owns relationship mechanics. This profile owns every fact that is
// specific to this repository: identifier grammar, verification lanes, and the
// canonical locations of registries, fixtures, sources, and projections.
const std = @import("std");

/// Verification lanes declared by this repository.
pub const Suite = enum {
    u,
    sm,
    r,
    a,
    pty,
    sim,
    m,
    all,
};

/// Concrete verification lanes emitted by generated projections and build gates.
pub const concrete_suites = [_]Suite{ .u, .sm, .r, .a, .pty, .sim, .m };
pub const wildcard_suite: Suite = .all;

/// Whether a concrete lane runs in the ordinary local gate.
pub fn suiteRunsLocally(suite: Suite) bool {
    return switch (suite) {
        .u, .sm, .r, .a, .sim => true,
        .pty, .m, .all => false,
    };
}

/// A required lane matches an observed lane, honoring the wildcard lane.
pub fn suiteMatches(required: Suite, observed: Suite) bool {
    if (required == .all) return true;
    return required == observed;
}

/// A concrete lane is a single observable suite rather than the wildcard.
pub fn suiteIsConcrete(suite: Suite) bool {
    return suite != .all;
}

pub fn requirementIdValid(id: []const u8) bool {
    if (!std.mem.startsWith(u8, id, "TJ-")) return false;
    const final_hyphen = std.mem.lastIndexOfScalar(u8, id, '-') orelse return false;
    if (final_hyphen <= 3 or final_hyphen + 3 != id.len) return false;
    for (id[3..final_hyphen]) |byte| if (!std.ascii.isUpper(byte)) return false;
    for (id[final_hyphen + 1 ..]) |byte| if (!std.ascii.isDigit(byte)) return false;
    return true;
}

/// How this repository invokes the specification tool.
pub const tool_invocation = "zig build spec-tool --";
pub const generate_command = "zig build update-spec";
pub const verify_command = "zig build check";

/// Untracked directory holding transient suite-evidence records written by
/// the build graph after fresh suite runs. The directory is build output:
/// it is git-ignored, never a tracked projection, and never gate evidence
/// beyond the suite-execution facts defined in `spec/ENGINE.md`.
pub const evidence_dir = "zig-evidence";

/// Render a requirement owner as a link from the generated requirement index.
pub fn requirementOwnerLink(owner: []const u8) []const u8 {
    return if (std.mem.startsWith(u8, owner, "spec/")) owner["spec/".len..] else owner;
}

pub const paths = struct {
    pub const documents = "spec/model/documents.zon";
    pub const concepts = "spec/model/concepts.zon";
    pub const requirements = "spec/model/requirements.zon";
    pub const test_specs = "spec/model/tests.zon";
    pub const verification = "spec/model/verification.zon";
    pub const implementations = "spec/model/implementation.zon";
    pub const test_bindings = "tests/implementations.zon";

    pub const fixture_root = "spec/fixtures/";
    pub const binding_root = "tests/";
    pub const binding_inventory_root = "tests/fixtures";
    pub const implementation_root = "src/";
    pub const implementation_inventory_root = "src";

    pub const agents = "AGENTS.md";
    pub const requirements_index = "spec/REQUIREMENTS.md";
    pub const glossary = "spec/GLOSSARY.md";
};

/// Human-readable preambles for profile-owned generated documents.
pub const projections = struct {
    pub const glossary_preamble =
        \\# Glossary
        \\
        \\Generated from `spec/model/concepts.zon`; do not edit this file directly.
        \\The structured registry owns concept identity, terminology, definitions,
        \\relationships, and requirement references.
        \\
    ;
    pub const requirements_preamble =
        \\# Requirement manifest
        \\
        \\Generated from `spec/model/requirements.zon`; do not edit this file directly.
        \\The linked owner text is authoritative. Revision 1 is the migration baseline and makes no
        \\claim about unrecorded history.
        \\
        \\Suite tags are `U` unit or policy, `SM` state machine, `R` rendering, `A` adapter or
        \\synthetic integration, `PTY` pseudo-terminal, `SIM` simulation, and `M` manual or
        \\capable-platform evidence.
        \\
    ;
};

test "requirement owner links are relative to the requirement index" {
    try std.testing.expectEqualStrings("PRODUCT.md", requirementOwnerLink("spec/PRODUCT.md"));
    try std.testing.expectEqualStrings("docs/PRODUCT.md", requirementOwnerLink("docs/PRODUCT.md"));
}

test "requirement identifiers follow the repository grammar" {
    try std.testing.expect(requirementIdValid("TJ-CORE-01"));
    try std.testing.expect(!requirementIdValid("TJ-core-01"));
    try std.testing.expect(!requirementIdValid("CORE-01"));
    try std.testing.expect(suiteMatches(.all, .pty));
    try std.testing.expect(!suiteMatches(.u, .pty));
}