flagon-io/g1t

public

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t/services/context/src/catalog.test.ts

157 lines8,280 bytesCodeBlame

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API1import { test } from "node:test";
2import assert from "node:assert/strict";
3
4import { assemble, authorsOf } from "./assemble.ts";
5import { extract } from "./extract.ts";
6import { composeRunContext, HEADER } from "./runcontext.ts";
7import { evaluate } from "./scorecards.ts";
8import { indexFilter, merge, readable, allowedKinds } from "./visibility.ts";
9
10const project = {
11 id: "prj_1",
12 workspace: "acme",
13 slug: "web",
14 name: "web",
15 description: "The storefront.",
16 private: true,
17 repoId: "rep_1",
18 repo: { namespace: "acme", name: "web" },
19 rootDir: "",
20 defaultBranch: "main",
21};
22const ctx = { project: "web", siblings: ["package-lock.json"] };
23
24test("a project's entities and relations come from its files and surroundings", () => {
25 const files = [
26 { path: "package.json", facts: extract("package.json", JSON.stringify({ name: "@acme/web", scripts: { test: "vitest" }, dependencies: { "@acme/ui": "*" } }), ctx) },
27 { path: "README.md", facts: extract("README.md", "# Web\n\nThe storefront.", ctx) },
28 { path: "wrangler.jsonc", facts: extract("wrangler.jsonc", '{"name":"web","routes":["shop.acme.com/*"]}', ctx) },
29 { path: ".g1t/workflows/ci.yml", facts: extract(".g1t/workflows/ci.yml", "run: npm test", ctx) },
30 ];
31 const built = assemble(project, files, {
32 owners: ["ana"],
33 dependsOn: [{ slug: "api", as: "API_URL" }],
34 deploy: { enabled: true, production: { url: "https://web--acme.g1t.page", commit: "abcdef1234", deployedAt: "2026-10-01T00:00:00Z" }, previews: 2, latest: null },
35 integrations: [{ id: "int_1", provider: "sentry", name: "Sentry", kind: "alerts", repo: "acme/web" }],
36 });
37 const keys = built.entities.map((entity) => `${entity.kind}:${entity.key}`);
38 for (const key of ["project:web", "owner:ana", "language:javascript", "package:npm:@acme/web", "doc:web:README.md", "api:web:worker:web", "app:web", "environment:web/production", "environment:web/preview"]) {
39 assert.ok(keys.includes(key), `${key} in ${keys.join(", ")}`);
40 }
41 const relations = built.relations.map((r) => `${r.from.kind}:${r.from.key} ${r.kind} ${r.to.kind}:${r.to.key}`);
42 for (const relation of [
43 "project:web depends_on project:api",
44 "project:web owned_by owner:ana",
45 "project:web documented_by doc:web:README.md",
46 "project:web exposes package:npm:@acme/web",
47 "package:npm:@acme/web depends_on package:npm:@acme/ui",
48 "app:web deploys_to environment:web/production",
49 "app:web exposes api:web:worker:web",
50 "project:web uses language:javascript",
51 "project:web uses integration:int_1",
52 ]) {
53 assert.ok(relations.includes(relation), relation);
54 }
55 assert.equal(built.tests, true);
56 const entry = built.entities.find((entity) => entity.kind === "project")!;
57 assert.match(entry.summary!, /The storefront\. Written in JavaScript\. .*Uses api\. Owned by ana\./);
58 assert.equal(entry.data.productionUrl, "https://web--acme.g1t.page");
59});
60
61test("the same inputs build the same catalog", () => {
62 const files = [{ path: "go.mod", facts: extract("go.mod", "module x/y\n", ctx) }];
63 const around = { owners: [], dependsOn: [], deploy: null, integrations: [] };
64 assert.deepEqual(assemble(project, files, around), assemble(project, files, around));
65 // Without deployments there is no app or environment.
66 assert.ok(!assemble(project, files, around).entities.some((entity) => entity.kind === "app" || entity.kind === "environment"));
67});
68
69test("owners are the members who wrote a fifth or more of the recent commits", () => {
70 const commit = (name: string, email = `${name}@example.com`) => ({ author: { name, email } });
71 const commits = [...Array(6)].map(() => commit("Ana")).concat([commit("someone", "bo@acme.com"), commit("bot"), commit("bot"), commit("cy")]);
72 assert.deepEqual(authorsOf(commits, ["ana", "bo", "cy"]), ["ana"]);
73 assert.deepEqual(authorsOf([commit("x", "bo@acme.com")], ["bo"]), ["bo"]);
74 assert.deepEqual(authorsOf([], ["ana"]), []);
75});
76
77test("scorecards pass, fail with a fix, or do not apply", () => {
78 const rules = evaluate({
79 name: "web",
80 owners: [],
81 docs: ["README.md"],
82 tests: false,
83 testCommand: "npm test",
84 deploy: { enabled: true, production: null, latest: { kind: "production", status: "failed", error: "build failed" } },
85 secretFindings: null,
86 });
87 const by = Object.fromEntries(rules.map((rule) => [rule.rule, rule]));
88 assert.equal(by.has_owner.status, "fail");
89 assert.deepEqual(by.has_owner.fix?.checks, ["grep -q '^owners:' .g1t/project.yml"]);
90 assert.equal(by.has_readme.status, "pass");
91 assert.equal(by.has_readme.fix, null);
92 assert.equal(by.has_agents_md.fix?.title, "Add an AGENTS.md to web");
93 assert.match(by.tests_in_ci.fix!.body, /`npm test`/);
94 assert.equal(by.production_green.status, "fail");
95 assert.match(by.production_green.detail, /build failed/);
96 assert.equal(by.no_secret_findings.status, "na");
97 const quiet = evaluate({ name: "lib", owners: ["ana"], docs: ["readme.md", "CLAUDE.md"], tests: true, testCommand: null, deploy: null, secretFindings: 0 });
98 assert.deepEqual(quiet.map((rule) => rule.status), ["pass", "pass", "pass", "pass", "na", "pass"]);
99});
100
101test("the run context marks its sources and keeps to its budget", () => {
102 const input = {
103 projects: [
104 {
105 slug: "web",
106 name: "web",
107 repo: "acme/web",
108 rootDir: "",
109 languages: ["TypeScript"],
110 packages: ["@acme/web"],
111 testCommands: ["npm test"],
112 owners: ["ana"],
113 dependsOn: [{ slug: "api", as: "API_URL", url: "https://api--acme.g1t.page" }],
114 usedBy: [],
115 environments: [{ name: "Production", url: "https://web--acme.g1t.page", status: "ready" }],
116 docs: ["README.md"],
117 },
118 ],
119 memories: [{ id: "mem_1", kind: "gotcha", text: "Tests need TZ=UTC.", source: "AGENTS.md" }],
120 decisions: [{ id: "mem_2", kind: "decision", text: "Decided in #12: keep v1 webhooks.", source: "#12" }],
121 budget: 4000,
122 };
123 const { text, sources } = composeRunContext(input);
124 assert.ok(text!.startsWith(HEADER));
125 assert.match(text!, /Project web \(acme\/web\) \[source: catalog\]:/);
126 assert.match(text!, /Uses: api at https:\/\/api--acme\.g1t\.page \(its address is in API_URL\)/);
127 assert.match(text!, /\[gotcha\] Tests need TZ=UTC\. \[source: AGENTS\.md\]/);
128 assert.match(text!, /Recent decisions:\n- Decided in #12: keep v1 webhooks\. \[source: #12\]/);
129 assert.deepEqual(sources.sort(), ["catalog:web", "memory:mem_1", "memory:mem_2"]);
130 const tight = composeRunContext({ ...input, budget: HEADER.length + 120 });
131 assert.ok(tight.text!.length <= HEADER.length + 120);
132 assert.deepEqual(composeRunContext({ projects: [], memories: [], decisions: [], budget: 4000 }), { text: null, sources: [] });
133});
134
135test("search reads one workspace, and only what a reader may see", () => {
136 const member = { workspace: "acme", member: true, visible: new Set<string>() };
137 const outsider = { workspace: "acme", member: false, visible: new Set(["site"]) };
138 assert.deepEqual(indexFilter(member, {}), { workspace: "acme" });
139 assert.deepEqual(indexFilter(outsider, { project: "site", kinds: ["memory", "doc"] }), { workspace: "acme", private: false, project: "site", kind: { $in: ["doc"] } });
140 assert.ok(!(allowedKinds(outsider) ?? []).includes("memory"));
141 const row = { workspace: "acme", kind: "doc", project: "site", private: false };
142 assert.ok(readable(row, outsider));
143 assert.ok(!readable({ ...row, workspace: "other" }, member), "never another workspace");
144 assert.ok(!readable({ ...row, private: true }, outsider));
145 assert.ok(!readable({ ...row, kind: "memory" }, outsider), "memory is for members");
146 assert.ok(!readable({ ...row, project: "made-private-since" }, outsider));
147 assert.ok(readable({ ...row, kind: "memory", private: true }, member));
148});
149
150test("semantic hits come first, without repeats", () => {
151 const hit = (id: string, score: number) => ({ kind: "doc" as const, id, title: id, snippet: "", project: null, url: null, score, source: "doc", by: null, updatedAt: null });
152 assert.deepEqual(
153 merge([hit("a", 0.5), hit("b", 0.9)], [hit("a", 0.2), hit("c", 0.2)], 10).map((h) => h.id),
154 ["b", "a", "c"],
155 );
156 assert.equal(merge([hit("a", 1)], [hit("b", 1)], 1).length, 1);
157});