@intentius/chant 0.83.0 → 0.84.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -22,6 +22,8 @@ import { contract, git, REPO, validSchema } from "./__fixtures__/contract-repo";
22
22
  import checkSchema from "./check.schema.json";
23
23
  import { workspaceGraph } from "./graph-cli";
24
24
  import graphSchema from "./graph.schema.json";
25
+ import { intentGraph } from "./intent";
26
+ import intentSchema from "./intent.schema.json";
25
27
  import { runChecks } from "./lineage-check";
26
28
  import { listWorkspace } from "./ls";
27
29
  import lsSchema from "./ls.schema.json";
@@ -35,7 +37,7 @@ import statusSchema from "./status.schema.json";
35
37
  const FIXTURE = join(REPO, "reference-workspace");
36
38
  const TIMEOUT = 240_000;
37
39
 
38
- const SCHEMAS = { ls: lsSchema, graph: graphSchema, check: checkSchema, status: statusSchema, records: recordsSchema };
40
+ const SCHEMAS = { ls: lsSchema, graph: graphSchema, check: checkSchema, status: statusSchema, records: recordsSchema, intent: intentSchema };
39
41
 
40
42
  /** This checkout's chant, started the way the CLI starts it, for members with no toolchain of their own. */
41
43
  const reader: Toolchain = {
@@ -116,6 +118,19 @@ describe("every schema against the reference workspace (#2543)", () => {
116
118
  expect(doc.members.map((m) => m.name)).toEqual(["app", "delivery", "design-client", "design"]);
117
119
  });
118
120
 
121
+ test("graph --intent, in the working tree and at HEAD (#2651)", async () => {
122
+ const { expectValid } = contract(intentSchema);
123
+ for (const at of [undefined, "HEAD"]) {
124
+ const { doc, failed } = await intentGraph({ cwd: FIXTURE, region: "app/src/server.mjs:19", at, kinds: ["decisions/decision.kind.mjs"] });
125
+ expectValid(doc);
126
+ if ("error" in doc) throw new Error(doc.error.message);
127
+ expect(failed).toBe(false);
128
+ expect(doc.workspace).toEqual({ name: "reference", root: "reference-workspace" });
129
+ expect(doc.at).toBe(at ? head : null);
130
+ expect(doc.region).toBe("region:app/src/server.mjs:19");
131
+ }
132
+ });
133
+
119
134
  test("records, in the working tree and at HEAD", async () => {
120
135
  const { expectValid } = contract(recordsSchema);
121
136
  for (const at of [undefined, "HEAD"]) {
@@ -12,6 +12,7 @@ import { REPO } from "./__fixtures__/contract-repo";
12
12
  import { MEMBER_RUN_REASON_CODES } from "./compose-graph";
13
13
  import { WORKSPACE_ERROR_CODES } from "./declaration";
14
14
  import { GRAPH_ERROR_CODES } from "./graph-cli";
15
+ import { INTENT_ERROR_CODES, INTENT_FINDING_CODES, INTENT_REASON_CODES } from "./intent";
15
16
  import { CHECK_CODES, CHECK_ERROR_CODES } from "./lineage-check";
16
17
  import { GROUP_REASON_CODES, MEMBER_REASON_CODES } from "./ls";
17
18
  import { isReasonCode, REASON_CODES, REASONS } from "./reason-codes";
@@ -33,6 +34,9 @@ const PER_COMMAND: Record<string, readonly string[]> = {
33
34
  RECORD_REASON_CODES,
34
35
  RECORD_WARNING_CODES,
35
36
  READ_ERROR_CODES,
37
+ INTENT_ERROR_CODES,
38
+ INTENT_FINDING_CODES,
39
+ INTENT_REASON_CODES,
36
40
  };
37
41
 
38
42
  /** Every string in an `enum` under a property named `code`, anywhere in a schema. */
@@ -94,7 +98,7 @@ describe("the closed list of reason codes", () => {
94
98
  });
95
99
 
96
100
  test("no source file emits a code outside the list", () => {
97
- const emitted = /(?:\bcode:\s*|(?:WorkspaceReadError|RecordReadError|StatusError)\(\s*)"([a-z0-9-]+)"/g;
101
+ const emitted = /(?:\bcode:\s*|(?:WorkspaceReadError|RecordReadError|StatusError|IntentError)\(\s*)"([a-z0-9-]+)"/g;
98
102
  let seen = 0;
99
103
  for (const file of sourceFiles(HERE)) {
100
104
  const text = readFileSync(file, "utf-8");
@@ -71,6 +71,24 @@ export const REASONS = {
71
71
  "schema-id-mismatch": "The schema's $id differs from the id the record kind names.",
72
72
  "schema-invalid": "The record schema itself does not compile.",
73
73
  "location-missing": "The records directory does not exist, in the tree or at the revision.",
74
+ // The intent graph (graph --intent, #2651): a read that fails.
75
+ "intent-region-invalid": "The region's path, or its line range, does not exist in the tree read.",
76
+ // The intent graph: part of the walk that can't be read. The document is still printed.
77
+ "intent-history-shallow": "The repository is a shallow clone, so the region's history stops at the clone's boundary.",
78
+ "intent-plugin-failed": "A kind file's commitJoins, which joins commits to units, contracts and evidence, failed for a commit.",
79
+ // The intent graph: findings, each a node in the graph.
80
+ "intent-commit-undecided": "A commit changed the region when no decision constrained it at path granularity.",
81
+ "intent-commit-bare": "A commit names no unit, no pull request and no decision covering the region at its time.",
82
+ "intent-pin-drifted": "A decision's pinned artifact no longer hashes to the pin.",
83
+ "intent-pin-missing": "A decision's pinned artifact does not exist in the tree read.",
84
+ "intent-artifact-unpinned": "An artifact decisions in the graph pinned, which no current decision pins.",
85
+ "intent-decision-superseded-live": "Every decision constraining the region is superseded.",
86
+ "intent-decision-provisional": "The current decisions constraining the region are all in states their kind does not close, such as decided.",
87
+ "intent-constraint-coarse": "The region is constrained only through its member, not by path.",
88
+ "intent-constraint-lost": "A decision's path constraint names a path that does not exist in the tree read.",
89
+ "intent-evidence-unpinned": "A decision's evidence has no hash: a URL, or a path with no sha256.",
90
+ "intent-trailer-unverified": "A commit carries a trailer a plugin says claims authorship, and the commit is not attested.",
91
+ "intent-region-unconstrained": "No decision constrains the region at any granularity.",
74
92
  // The lineage lock (check).
75
93
  "lock-invalid": "The lineage lock can't be read.",
76
94
  "manual-step-open": "A scope in the lineage lock has an open manual step.",
@@ -187,7 +187,7 @@ export interface LoadedRecordKind {
187
187
  * The kind is registered under a name no lexicon package can have (npm names
188
188
  * hold no `:`), imported and unregistered again, so no lexicon lookup sees it.
189
189
  */
190
- async function importKindModule(path: string): Promise<Record<string, unknown>> {
190
+ export async function importKindModule(path: string): Promise<Record<string, unknown>> {
191
191
  const name = `record-kind:${path}`;
192
192
  registerLexiconDeclarations([{ name, module: path }], dirname(path));
193
193
  try {