dw-sdlc 0.0.0-stage → 0.1.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.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +63 -2
  3. package/config/agentic.config.schema.json +212 -0
  4. package/config/references.schema.json +56 -0
  5. package/dist/agentic-config.d.ts +167 -0
  6. package/dist/agentic-config.js +307 -0
  7. package/dist/catalogue.d.ts +36 -0
  8. package/dist/catalogue.js +74 -0
  9. package/dist/checks/agents-map.d.ts +7 -0
  10. package/dist/checks/agents-map.js +166 -0
  11. package/dist/checks/check.d.ts +17 -0
  12. package/dist/checks/check.js +21 -0
  13. package/dist/checks/index.d.ts +8 -0
  14. package/dist/checks/index.js +19 -0
  15. package/dist/checks/primitives.d.ts +8 -0
  16. package/dist/checks/primitives.js +128 -0
  17. package/dist/cli.d.ts +2 -0
  18. package/dist/cli.js +43 -0
  19. package/dist/commands/config.d.ts +2 -0
  20. package/dist/commands/config.js +76 -0
  21. package/dist/commands/doctor.d.ts +57 -0
  22. package/dist/commands/doctor.js +341 -0
  23. package/dist/commands/gate.d.ts +2 -0
  24. package/dist/commands/gate.js +175 -0
  25. package/dist/commands/primitives.d.ts +2 -0
  26. package/dist/commands/primitives.js +106 -0
  27. package/dist/commands/references-setup.d.ts +2 -0
  28. package/dist/commands/references-setup.js +213 -0
  29. package/dist/commands/references-sync.d.ts +2 -0
  30. package/dist/commands/references-sync.js +347 -0
  31. package/dist/commands/setup.d.ts +31 -0
  32. package/dist/commands/setup.js +369 -0
  33. package/dist/json-schema.d.ts +8 -0
  34. package/dist/json-schema.js +227 -0
  35. package/dist/markdown.d.ts +19 -0
  36. package/dist/markdown.js +77 -0
  37. package/dist/pins.d.ts +16 -0
  38. package/dist/pins.js +83 -0
  39. package/dist/references-key.d.ts +31 -0
  40. package/dist/references-key.js +150 -0
  41. package/dist/report.d.ts +13 -0
  42. package/dist/report.js +29 -0
  43. package/dist/router-block.d.ts +13 -0
  44. package/dist/router-block.js +62 -0
  45. package/dist/setup-rules.d.ts +22 -0
  46. package/dist/setup-rules.js +98 -0
  47. package/package.json +30 -3
  48. package/templates/router.md +38 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dominik Woźniak
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,64 @@
1
- # Temporary Holding Version
1
+ # dw-sdlc
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ The Gate and the agentic config of a repository. `.ai/agentic.config.json` declares how a repository
4
+ works for an agent: its package manager, protected branches, env-file policy, commit convention and
5
+ the Gate. The package ships the `dw-sdlc` bin that runs on that file, its JSON Schema, and the
6
+ resolver of its layers.
7
+
8
+ ## Install
9
+
10
+ Node 24 or later.
11
+
12
+ ```sh
13
+ pnpm add -D dw-sdlc
14
+ ```
15
+
16
+ ## The Gate
17
+
18
+ `dw-sdlc gate` runs the Steps under `gate.steps` in order from the repository root, then every Check
19
+ under `gate.checks`. It exits 0 when everything passes, 1 when a Step or a Check fails, and 2 when the
20
+ Gate cannot run. `--json` prints the result as one document.
21
+
22
+ ```json
23
+ {
24
+ "$schema": "../node_modules/dw-sdlc/config/agentic.config.schema.json",
25
+ "version": 1,
26
+ "gate": {
27
+ "steps": ["pnpm lint", "pnpm typecheck", "pnpm test"]
28
+ }
29
+ }
30
+ ```
31
+
32
+ ```json
33
+ { "scripts": { "check": "dw-sdlc gate" } }
34
+ ```
35
+
36
+ ## Commands
37
+
38
+ | command | what it does |
39
+ | ------------------ | ----------------------------------------------------------------------------------- |
40
+ | `gate` | the Steps of `gate.steps` in order, then every Check under `gate.checks` |
41
+ | `primitives` | the Primitives that own each path, with their summaries and documents |
42
+ | `setup` | this machine's local config layer, the git excludes and the permission rules |
43
+ | `doctor` | one PASS / WARN / FAIL line per machine check the guardrails rely on |
44
+ | `config` | the resolved agentic config, or one file validated against the schema |
45
+ | `references sync` | every declared Reference brought to its ref under `references/` |
46
+ | `references setup` | the Router, its table and the ignore rules a repository needs to declare References |
47
+
48
+ `dw-sdlc <command> --help` gives each one's options.
49
+
50
+ ## The resolver
51
+
52
+ ```ts
53
+ import { resolveConfig } from "dw-sdlc"
54
+
55
+ const { config, problems } = resolveConfig(process.cwd())
56
+ ```
57
+
58
+ `resolveConfig` merges the committed `.ai/agentic.config.json`, the machine's
59
+ `.ai/agentic.config.local.json` and what it infers from the repository. `problems` names each layer
60
+ that fails the schema; an invalid layer is dropped whole.
61
+
62
+ ## License
63
+
64
+ MIT
@@ -0,0 +1,212 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://raw.githubusercontent.com/dominikwozniak/dw-sdlc/main/plugins/guardrails/config/agentic.config.schema.json",
4
+ "title": "agentic.config",
5
+ "description": "How a repository works for an agent. `.ai/agentic.config.json` is committed; `.ai/agentic.config.local.json` overrides it on one machine and may tighten `guardrails` but never loosen it. A key neither file sets is inferred: the Node package manager from the lockfile, the `conventional` commit preset, and `gate.command` from the manifest's `check` script. Unknown top-level keys are tolerated so other tool families can share the file; the keys named here refuse unknown children.",
6
+ "type": "object",
7
+ "properties": {
8
+ "$schema": {
9
+ "type": "string"
10
+ },
11
+ "version": {
12
+ "const": 1
13
+ },
14
+ "baseBranch": {
15
+ "description": "The branch pull requests target; `auto` reads the remote's default branch.",
16
+ "type": "string",
17
+ "minLength": 1
18
+ },
19
+ "packageManagers": {
20
+ "type": "object",
21
+ "properties": {
22
+ "node": {
23
+ "description": "Inferred from the lockfile. The package-manager guard refuses the other Node package managers only when this is `pnpm`.",
24
+ "enum": ["pnpm", "npm", "yarn", "bun"]
25
+ },
26
+ "ruby": {
27
+ "description": "Accepted so a repository can declare it; no guard reads it and nothing infers it.",
28
+ "enum": ["bundler"]
29
+ }
30
+ },
31
+ "additionalProperties": false
32
+ },
33
+ "guardrails": {
34
+ "description": "Policy the local override may tighten and never loosen. Every enum lists its strictest value first.",
35
+ "type": "object",
36
+ "properties": {
37
+ "forcePush": {
38
+ "description": "`deny` refuses every force push. `lease` lets `--force-with-lease` and `--force-if-includes` through to a branch outside `protectedBranches`; bare `--force` and `-f` stay refused. `ask` is `lease` with a permission prompt for each lease push it lets through. Strictest first: deny, ask, lease.",
39
+ "enum": ["deny", "ask", "lease"]
40
+ },
41
+ "commitOnProtected": {
42
+ "description": "`deny` refuses a `git commit`, `merge`, `cherry-pick` or `revert` on a branch listed in `protectedBranches`, so every change starts on a branch of its own. `allow` lets it through, for a repository that commits small fixes on its protected branch and pushes them from a person's terminal. Default `allow`. Strictest first: deny, allow.",
43
+ "enum": ["deny", "allow"]
44
+ },
45
+ "envFiles": {
46
+ "description": "Which env files (`.env`, `.env.*`, `.envrc`) an agent may read, edit or write. A candidate is judged in this order: listed in `deny` → refused; listed in `allow` → readable; `policy` `deny` → refused; `policy` `git` → readable when git tracks it, refused when git ignores it or does not know it. Entries are globs against the path relative to the repository root: `*` and `?` as in a shell pattern (`*` crosses `/`), a leading `**/` means at any depth, so `.env` is the one in the root and `**/.env.example` every file of that name. No brace groups. A path outside the repository root, or outside any repository, is judged by its basename against the `**/` entries alone. Defaults: policy `git`, allow the `.env.example`, `.env.sample` and `.env.template` names anywhere, deny nothing. The local override may drop `allow` entries and add `deny` entries, never the reverse.",
47
+ "type": "object",
48
+ "properties": {
49
+ "policy": {
50
+ "description": "What decides a candidate no list names. `deny` refuses it; `git` asks git: tracked passes, ignored or unknown is refused.",
51
+ "enum": ["deny", "git"]
52
+ },
53
+ "allow": {
54
+ "description": "Globs of the env files that are readable regardless of `policy`.",
55
+ "type": "array",
56
+ "items": {
57
+ "type": "string",
58
+ "minLength": 1
59
+ },
60
+ "uniqueItems": true
61
+ },
62
+ "deny": {
63
+ "description": "Globs of the env files that are refused regardless of `policy`; wins over `allow`.",
64
+ "type": "array",
65
+ "items": {
66
+ "type": "string",
67
+ "minLength": 1
68
+ },
69
+ "uniqueItems": true
70
+ }
71
+ },
72
+ "additionalProperties": false
73
+ },
74
+ "protectedBranches": {
75
+ "description": "Branches the guards refuse every push to: plain, lease or force. Under `commitOnProtected: deny` they refuse a commit, merge, cherry-pick or revert on one too. The local override may add to this list, never remove from it.",
76
+ "type": "array",
77
+ "items": {
78
+ "type": "string",
79
+ "minLength": 1
80
+ },
81
+ "uniqueItems": true
82
+ }
83
+ },
84
+ "additionalProperties": false
85
+ },
86
+ "commit": {
87
+ "type": "object",
88
+ "properties": {
89
+ "convention": {
90
+ "description": "The subject preset `pattern` falls back to. `ticket-key`: `[KEY-123] type: subject`, the tracker's key in brackets before a type from a fixed list. `conventional`: Conventional Commits; inferred when no layer sets either.",
91
+ "enum": ["ticket-key", "conventional"]
92
+ },
93
+ "pattern": {
94
+ "description": "POSIX ERE the commit subject must match; set, it wins over `convention`. `grep -E` runs it, so no `\\d`, `\\s`, `\\w`, `\\b` or `(?…)`. `.+` accepts any subject.",
95
+ "type": "string",
96
+ "minLength": 1,
97
+ "format": "regex"
98
+ },
99
+ "trailer": {
100
+ "description": "A trailer key, such as `Co-Authored-By`, that every commit message must carry on a line of its own.",
101
+ "type": "string",
102
+ "pattern": "^[A-Za-z][A-Za-z0-9-]*$"
103
+ }
104
+ },
105
+ "additionalProperties": false
106
+ },
107
+ "gate": {
108
+ "description": "The Gate `dw-sdlc gate` runs: the Steps under `steps` in order, then every Check under `checks`.",
109
+ "type": "object",
110
+ "properties": {
111
+ "command": {
112
+ "description": "The one command that runs the Gate, the same in a terminal and in CI. Inferred as `pnpm check` where `package.json` has a `check` script.",
113
+ "type": "string",
114
+ "minLength": 1
115
+ },
116
+ "steps": {
117
+ "description": "The Steps: toolchain commands run in order from the repository root through `sh -c`, each one's output passed through; the first that fails ends the Gate and no Check runs. A command the shell cannot find (exit 127) or execute (126) means the Gate cannot run.",
118
+ "type": "array",
119
+ "items": {
120
+ "type": "string",
121
+ "minLength": 1
122
+ }
123
+ },
124
+ "checks": {
125
+ "description": "The Checks the Gate runs after its steps, every one even when another fails: the `run` scripts first, then the Checks the package ships, in the order listed here. A Check the package ships is `true` for its defaults, an options object over them, or `false` to stay off. A key names a Check the package ships, and a name it does not ship is refused.",
126
+ "type": "object",
127
+ "properties": {
128
+ "run": {
129
+ "description": "The repository's own scripts, each run like a Step and reported as a Check under its `name`: exit 0 passes, 127 or 126 means the Gate cannot run, any other code fails.",
130
+ "type": "array",
131
+ "items": {
132
+ "type": "object",
133
+ "properties": {
134
+ "name": {
135
+ "description": "The Check's name, which each of its failure lines carries: lowercase words joined by hyphens.",
136
+ "type": "string",
137
+ "pattern": "^[a-z][a-z0-9]*(-[a-z0-9]+)*$"
138
+ },
139
+ "command": {
140
+ "type": "string",
141
+ "minLength": 1
142
+ }
143
+ },
144
+ "required": ["name", "command"],
145
+ "additionalProperties": false
146
+ }
147
+ },
148
+ "primitives": {
149
+ "description": "The Primitives catalogue: unique ids, each in a group `groups` lists, a summary of one line within 120 characters, every `code` path on disk, every `docs` path on disk with its heading anchor resolving, and every file under `roots` named by the `code` of a Primitive, itself or a directory above it. A test file, under a `test`, `tests` or `__tests__` directory or named `*.test.*` or `*.spec.*`, needs no Primitive.",
150
+ "type": ["boolean", "object"],
151
+ "properties": {
152
+ "file": {
153
+ "description": "The catalogue, relative to the repository root. Default `.ai/primitives.json`.",
154
+ "type": "string",
155
+ "minLength": 1
156
+ },
157
+ "roots": {
158
+ "description": "The directories whose every file a Primitive names, relative to the repository root; one that does not exist names no file. Default `packages`, `plugins`, `scripts` and `src`.",
159
+ "type": "array",
160
+ "items": {
161
+ "type": "string",
162
+ "minLength": 1
163
+ },
164
+ "uniqueItems": true
165
+ }
166
+ },
167
+ "additionalProperties": false
168
+ },
169
+ "agents-map": {
170
+ "description": "The agent map: within its line and byte budget, naming the resolved `gate.command`, carrying a Task Router row to the Primitives catalogue where there is one, every path the Task Router points at existing, and the skills directory, `skills-lock.json` and the `.claude/skills` links in step where the repository has them.",
171
+ "type": ["boolean", "object"],
172
+ "properties": {
173
+ "file": {
174
+ "description": "The map, relative to the repository root. Default `AGENTS.md`.",
175
+ "type": "string",
176
+ "minLength": 1
177
+ },
178
+ "maxLines": {
179
+ "description": "Default 150.",
180
+ "type": "integer",
181
+ "minimum": 1
182
+ },
183
+ "maxBytes": {
184
+ "description": "Default 10240.",
185
+ "type": "integer",
186
+ "minimum": 1
187
+ }
188
+ },
189
+ "additionalProperties": false
190
+ }
191
+ },
192
+ "additionalProperties": false
193
+ }
194
+ },
195
+ "additionalProperties": false
196
+ },
197
+ "worktree": {
198
+ "type": "object",
199
+ "properties": {
200
+ "setup": {
201
+ "description": "Commands a fresh linked worktree needs before work starts. Reported at session start, not run.",
202
+ "type": "array",
203
+ "items": {
204
+ "type": "string",
205
+ "minLength": 1
206
+ }
207
+ }
208
+ },
209
+ "additionalProperties": false
210
+ }
211
+ }
212
+ }
@@ -0,0 +1,56 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://raw.githubusercontent.com/dominikwozniak/dw-sdlc/main/plugins/references/config/references.schema.json",
4
+ "title": "references",
5
+ "description": "The `references` key of `.ai/agentic.config.json`: the repositories an agent reads to see how a problem was solved before, each brought to its ref under `references/<dir>` by the Sync. Only the committed file is read; the local layer adds no References. Every `dir` is unique in the list, which this schema cannot say and the Sync refuses. A key the Sync refuses syncs nothing.",
6
+ "type": "array",
7
+ "items": {
8
+ "type": "object",
9
+ "properties": {
10
+ "dir": {
11
+ "description": "The one directory under `references/` the clone lives in: letters, digits, `_`, `.` and `-`, not starting with `.` or `-`.",
12
+ "type": "string",
13
+ "pattern": "^[A-Za-z0-9_][A-Za-z0-9_.-]*$"
14
+ },
15
+ "repository": {
16
+ "description": "A URL `git` can fetch. A `https://github.com/` one fetches with the GitHub CLI's credentials. No whitespace, and no leading `-`, which `git` would read as an option.",
17
+ "type": "string",
18
+ "pattern": "^[^\\s-]\\S*$"
19
+ },
20
+ "ref": {
21
+ "description": "A branch, whose head the clone moves to, or a tag. `{name}` in it stands for the exact version the root `package.json` pins for package `name`, read through the default catalog of `pnpm-workspace.yaml` when the pin says `catalog:` or `catalog:default`. No whitespace, and no leading `-`.",
22
+ "type": "string",
23
+ "pattern": "^[^\\s-]\\S*$"
24
+ },
25
+ "only": {
26
+ "description": "Paths the sparse checkout holds beside the repository's top-level files, relative to the clone and inside it; a directory ends in `/`. Absent, the whole tree is checked out. Present, it names at least one path, and a path the ref's tree lacks fails the Reference.",
27
+ "type": "array",
28
+ "minItems": 1,
29
+ "items": {
30
+ "type": "string",
31
+ "pattern": "^(?!/)(?!(?:.*/)?\\.\\.(?:/|$)).+$"
32
+ }
33
+ },
34
+ "skip": {
35
+ "description": "Paths the sparse checkout leaves out, relative to the clone and inside it. Empty or absent, nothing is left out. With `only`, each lies inside one of its paths, which this schema cannot say and the Sync refuses.",
36
+ "type": "array",
37
+ "items": {
38
+ "type": "string",
39
+ "pattern": "^(?!/)(?!(?:.*/)?\\.\\.(?:/|$)).+$"
40
+ }
41
+ },
42
+ "what": {
43
+ "description": "What the Reference is.",
44
+ "type": "string",
45
+ "minLength": 1
46
+ },
47
+ "when": {
48
+ "description": "When an agent reaches for it.",
49
+ "type": "string",
50
+ "minLength": 1
51
+ }
52
+ },
53
+ "required": ["dir", "repository", "ref", "what", "when"],
54
+ "additionalProperties": false
55
+ }
56
+ }
@@ -0,0 +1,167 @@
1
+ export declare const COMMITTED_FILE = ".ai/agentic.config.json";
2
+ export declare const LOCAL_FILE = ".ai/agentic.config.local.json";
3
+ /** The schema's path inside this package. */
4
+ export declare const SCHEMA_FILE = "config/agentic.config.schema.json";
5
+ export declare const SCHEMA_PATH: string;
6
+ export declare const COMMIT_CONVENTIONS: readonly ["ticket-key", "conventional"];
7
+ export type CommitConvention = (typeof COMMIT_CONVENTIONS)[number];
8
+ export type NodePackageManager = "pnpm" | "npm" | "yarn" | "bun";
9
+ export type ForcePush = "deny" | "ask" | "lease";
10
+ export type CommitOnProtected = "deny" | "allow";
11
+ export type EnvPolicy = "deny" | "git";
12
+ /** Which env files may be read: `deny` list, then `allow` list, then `policy` for the rest. */
13
+ export type EnvFiles = {
14
+ policy: EnvPolicy;
15
+ allow: string[];
16
+ deny: string[];
17
+ };
18
+ export type Guardrails = {
19
+ forcePush: ForcePush;
20
+ commitOnProtected: CommitOnProtected;
21
+ envFiles: EnvFiles;
22
+ protectedBranches: string[];
23
+ };
24
+ /** `guardrails` as one layer writes it: every key optional, `envFiles` key by key. */
25
+ export type GuardrailsLayer = Partial<Omit<Guardrails, "envFiles">> & {
26
+ envFiles?: Partial<EnvFiles>;
27
+ };
28
+ /** A repository's own script under `gate.checks.run`, reported as a Check under `name`. */
29
+ export type RunCheck = {
30
+ name: string;
31
+ command: string;
32
+ };
33
+ /**
34
+ * `run`, and under each other key a Check the package ships, as the schema takes it: `true`, `false` or
35
+ * its options. `src/checks/` reads the setting of each.
36
+ */
37
+ export type GateChecks = {
38
+ run: RunCheck[];
39
+ [check: string]: unknown;
40
+ };
41
+ /** The Gate: its command, the steps run in order, the Checks run after them. */
42
+ export type Gate = {
43
+ command?: string;
44
+ steps: string[];
45
+ checks: GateChecks;
46
+ };
47
+ /** `gate` as one layer writes it: every key optional, `checks` Check by Check. */
48
+ export type GateLayer = {
49
+ command?: string;
50
+ steps?: string[];
51
+ checks?: Partial<GateChecks>;
52
+ };
53
+ /** One layer as written in a file: every key optional, unknown top-level keys tolerated. */
54
+ export type AgenticConfig = {
55
+ $schema?: string;
56
+ version?: 1;
57
+ baseBranch?: string;
58
+ packageManagers?: {
59
+ node?: NodePackageManager;
60
+ ruby?: "bundler";
61
+ };
62
+ guardrails?: GuardrailsLayer;
63
+ commit?: {
64
+ convention?: CommitConvention;
65
+ pattern?: string;
66
+ trailer?: string;
67
+ };
68
+ gate?: GateLayer;
69
+ worktree?: {
70
+ setup?: string[];
71
+ };
72
+ };
73
+ /** What the guards see: every layer applied, every key present. */
74
+ export type ResolvedConfig = {
75
+ version: 1;
76
+ baseBranch: string;
77
+ packageManagers: {
78
+ node?: NodePackageManager;
79
+ ruby?: "bundler";
80
+ };
81
+ guardrails: Guardrails;
82
+ commit: {
83
+ convention: CommitConvention;
84
+ pattern: string;
85
+ trailer?: string;
86
+ };
87
+ gate: Gate;
88
+ worktree: {
89
+ setup: string[];
90
+ };
91
+ };
92
+ /** The layers merged, before `commit.pattern` falls back to the preset its convention names. */
93
+ type Merged = Omit<ResolvedConfig, "commit"> & {
94
+ commit: {
95
+ convention: CommitConvention;
96
+ pattern?: string;
97
+ trailer?: string;
98
+ };
99
+ };
100
+ export type Problem = {
101
+ file: string;
102
+ path: string;
103
+ message: string;
104
+ };
105
+ export type LayerState = "absent" | "valid" | "invalid";
106
+ export type Resolution = {
107
+ config: ResolvedConfig;
108
+ problems: Problem[];
109
+ layers: {
110
+ committed: LayerState;
111
+ local: LayerState;
112
+ };
113
+ /** The checkout each layer was read from: the root, or the main checkout for a worktree lacking it. */
114
+ sources: {
115
+ committed: string | undefined;
116
+ local: string | undefined;
117
+ };
118
+ };
119
+ /** Strictest value first; the local override may only move towards the front. */
120
+ export declare const STRICTNESS: {
121
+ readonly forcePush: readonly ["deny", "ask", "lease"];
122
+ readonly commitOnProtected: readonly ["deny", "allow"];
123
+ readonly envFiles: readonly ["deny", "git"];
124
+ };
125
+ /** What the guards run on while any layer is invalid. */
126
+ export declare const STRICTEST_GUARDRAILS: Guardrails;
127
+ /** What a repository gets with nothing declared. */
128
+ export declare const DEFAULT_GUARDRAILS: Guardrails;
129
+ /**
130
+ * Whether an `envFiles` glob selects the file at `relativePath` (to the repository root, or the
131
+ * basename outside one). `*` and `?` as in a shell pattern, `*` crossing `/`; a leading `**` and a
132
+ * slash mean at any depth. The same rule `hooks/block-env-access.sh` applies with `[[ == ]]`.
133
+ */
134
+ export declare function matchesEnvGlob(glob: string, relativePath: string): boolean;
135
+ export declare const COMMIT_PATTERNS: Record<CommitConvention, string>;
136
+ /**
137
+ * The schema's public `$id`: what a written config points its `$schema` at. Stable across plugin
138
+ * installs, where `SCHEMA_PATH` moves with every version.
139
+ */
140
+ export declare function schemaId(): string;
141
+ /** Parses and validates one document; `file` names it in every problem. */
142
+ export declare function validateDocument(file: string, text: string): {
143
+ value: AgenticConfig;
144
+ } | {
145
+ problems: Problem[];
146
+ };
147
+ /** The top level of the repository holding `dir`, or undefined outside one. */
148
+ export declare function findRepository(dir: string): string | undefined;
149
+ /** The top level of the repository holding `dir`, or `dir` itself outside one. */
150
+ export declare function repositoryRoot(dir: string): string;
151
+ /**
152
+ * The main checkout of the linked worktree at `root`, or undefined for a main checkout or outside a
153
+ * repository: a linked worktree's git dir differs from the common one, which sits in the main checkout.
154
+ */
155
+ export declare function mainCheckout(root: string): string | undefined;
156
+ /**
157
+ * The bottom layer: the package manager the lockfile implies, the Gate command the manifest's `check`
158
+ * script implies, plus the defaults every key falls back to. `commit.pattern` is left to
159
+ * `resolveConfig`, which fills it from the convention when no layer sets one.
160
+ */
161
+ export declare function inferConfig(root: string): Merged;
162
+ /**
163
+ * Local over committed over inferred, for the repository at `root`. A linked worktree reads a layer it
164
+ * lacks from its main checkout, where a repository that keeps `.ai/` out of git has the only copy.
165
+ */
166
+ export declare function resolveConfig(root: string): Resolution;
167
+ export {};