@kody-ade/kody-engine 0.4.620 → 0.4.622
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.
- package/README.md +3 -1
- package/dist/bin/kody.js +18 -5
- package/docs/delivery-boundary.md +29 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -57,7 +57,9 @@ key. It's built to keep that blast radius small:
|
|
|
57
57
|
downstream CI.
|
|
58
58
|
- **Write allowlist.** The agent commits through `commitAndPush`, which blocks
|
|
59
59
|
writes to engine runtime or configuration paths — it can't touch your
|
|
60
|
-
runtime state.
|
|
60
|
+
runtime state. See [Delivery boundary](docs/delivery-boundary.md) for what is
|
|
61
|
+
silently discarded, what fails visibly, and how an approved workflow file is
|
|
62
|
+
delivered.
|
|
61
63
|
- **Locked-toolbox mode.** A job can declare `tools: [...]` to drop `Bash` and
|
|
62
64
|
shell entirely, running only a fixed set of high-level intents.
|
|
63
65
|
- **Review like any contributor.** kody opens PRs; you merge them.
|
package/dist/bin/kody.js
CHANGED
|
@@ -15,7 +15,7 @@ var init_package = __esm({
|
|
|
15
15
|
"package.json"() {
|
|
16
16
|
package_default = {
|
|
17
17
|
name: "@kody-ade/kody-engine",
|
|
18
|
-
version: "0.4.
|
|
18
|
+
version: "0.4.622",
|
|
19
19
|
description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative implementation profiles.",
|
|
20
20
|
license: "MIT",
|
|
21
21
|
repository: {
|
|
@@ -29,6 +29,7 @@ var init_package = __esm({
|
|
|
29
29
|
files: [
|
|
30
30
|
"dist",
|
|
31
31
|
"templates",
|
|
32
|
+
"docs/delivery-boundary.md",
|
|
32
33
|
"kody.config.schema.json"
|
|
33
34
|
],
|
|
34
35
|
scripts: {
|
|
@@ -8927,6 +8928,9 @@ function isForbiddenPath(p, deliveryPathAllowlist = []) {
|
|
|
8927
8928
|
for (const pre of ALLOWED_PATH_PREFIXES) if (p.startsWith(pre)) return false;
|
|
8928
8929
|
return false;
|
|
8929
8930
|
}
|
|
8931
|
+
function isReportableDeliveryOmission(p) {
|
|
8932
|
+
return !GENERATED_PATH_PREFIXES.some((prefix) => p.startsWith(prefix)) && !FORBIDDEN_PATH_SUFFIXES.some((suffix) => p.endsWith(suffix));
|
|
8933
|
+
}
|
|
8930
8934
|
function isRecord(value) {
|
|
8931
8935
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8932
8936
|
}
|
|
@@ -9042,9 +9046,10 @@ function commitAndPush(branch, agentMessage, cwd, deliveryPathAllowlist = [], de
|
|
|
9042
9046
|
const forbiddenFiles = allChanged.filter(
|
|
9043
9047
|
(f) => isForbiddenPath(f, deliveryPathAllowlist) && !isTrustedConfigActivationChange(f, deliveryPathAllowlist, deliveryConfigAllowlist, cwd)
|
|
9044
9048
|
);
|
|
9049
|
+
const omittedFiles = forbiddenFiles.filter(isReportableDeliveryOmission);
|
|
9045
9050
|
const mergeHeadExists = fs29.existsSync(path28.join(cwd ?? process.cwd(), ".git", "MERGE_HEAD"));
|
|
9046
9051
|
if (allowedFiles.length === 0 && !mergeHeadExists) {
|
|
9047
|
-
return { committed: false, pushed: false, sha: "", message: "", omittedFiles
|
|
9052
|
+
return { committed: false, pushed: false, sha: "", message: "", omittedFiles };
|
|
9048
9053
|
}
|
|
9049
9054
|
for (const f of forbiddenFiles) {
|
|
9050
9055
|
try {
|
|
@@ -9072,9 +9077,9 @@ function commitAndPush(branch, agentMessage, cwd, deliveryPathAllowlist = [], de
|
|
|
9072
9077
|
const sha = git(["rev-parse", "HEAD"], cwd).slice(0, 7);
|
|
9073
9078
|
const pushResult = pushWithRetry({ cwd, branch, setUpstream: true });
|
|
9074
9079
|
if (pushResult.ok) {
|
|
9075
|
-
return { committed: true, pushed: true, sha, message, omittedFiles
|
|
9080
|
+
return { committed: true, pushed: true, sha, message, omittedFiles };
|
|
9076
9081
|
}
|
|
9077
|
-
return { committed: true, pushed: false, sha, message, pushError: pushResult.reason, omittedFiles
|
|
9082
|
+
return { committed: true, pushed: false, sha, message, pushError: pushResult.reason, omittedFiles };
|
|
9078
9083
|
}
|
|
9079
9084
|
function hasCommitsAhead(branch, defaultBranch, cwd) {
|
|
9080
9085
|
try {
|
|
@@ -9089,7 +9094,7 @@ function hasCommitsAhead(branch, defaultBranch, cwd) {
|
|
|
9089
9094
|
}
|
|
9090
9095
|
}
|
|
9091
9096
|
}
|
|
9092
|
-
var GIT_MAX_BUFFER_BYTES, FORBIDDEN_PATH_PREFIXES, ALLOWED_PATH_PREFIXES, FORBIDDEN_PATH_EXACT, FORBIDDEN_PATH_SUFFIXES, ACTIVATION_FIELDS, CONVENTIONAL_PREFIXES;
|
|
9097
|
+
var GIT_MAX_BUFFER_BYTES, FORBIDDEN_PATH_PREFIXES, ALLOWED_PATH_PREFIXES, FORBIDDEN_PATH_EXACT, FORBIDDEN_PATH_SUFFIXES, GENERATED_PATH_PREFIXES, ACTIVATION_FIELDS, CONVENTIONAL_PREFIXES;
|
|
9093
9098
|
var init_commit = __esm({
|
|
9094
9099
|
"src/commit.ts"() {
|
|
9095
9100
|
"use strict";
|
|
@@ -9113,6 +9118,14 @@ var init_commit = __esm({
|
|
|
9113
9118
|
ALLOWED_PATH_PREFIXES = [];
|
|
9114
9119
|
FORBIDDEN_PATH_EXACT = /* @__PURE__ */ new Set([".env", ".kody-pip-requirements.txt", "kody.config.json"]);
|
|
9115
9120
|
FORBIDDEN_PATH_SUFFIXES = [".log"];
|
|
9121
|
+
GENERATED_PATH_PREFIXES = [
|
|
9122
|
+
".kody-engine/",
|
|
9123
|
+
".kody-lean/",
|
|
9124
|
+
".codegraph/",
|
|
9125
|
+
"node_modules/",
|
|
9126
|
+
"dist/",
|
|
9127
|
+
"build/"
|
|
9128
|
+
];
|
|
9116
9129
|
ACTIVATION_FIELDS = [
|
|
9117
9130
|
"activeAgents",
|
|
9118
9131
|
"activeCapabilities",
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Delivery boundary
|
|
2
|
+
|
|
3
|
+
Kody may inspect the whole checkout, but it does not commit every changed file.
|
|
4
|
+
The postflight delivery step separates product work from runtime state and
|
|
5
|
+
operator-owned configuration before creating the PR.
|
|
6
|
+
|
|
7
|
+
## What happens to each kind of change
|
|
8
|
+
|
|
9
|
+
| Change | Result |
|
|
10
|
+
|---|---|
|
|
11
|
+
| Normal source, test, or documentation file | Committed and pushed to the task branch |
|
|
12
|
+
| Engine-generated cache or runtime state (`.kody-engine/`, `.kody-lean/`, `.codegraph/`, `node_modules/`, `dist/`, `build/`, logs) | Discarded from delivery without failing otherwise valid product work |
|
|
13
|
+
| Protected operator or security configuration (`.github/*.yml`, `.env`, `kody.config.json`, legacy `.kody/` state) | Excluded from the commit and reported as a blocked delivery; the run fails visibly instead of claiming full completion |
|
|
14
|
+
|
|
15
|
+
This distinction matters because definition hydration updates
|
|
16
|
+
`.kody-engine/definitions/manifest.json` on normal runs. That file belongs to
|
|
17
|
+
the Engine runtime; it is not work the agent attempted to deliver.
|
|
18
|
+
|
|
19
|
+
## Delivering an approved protected file
|
|
20
|
+
|
|
21
|
+
Do not weaken the global boundary. A capability that legitimately owns a
|
|
22
|
+
GitHub workflow or a repository loop definition must declare the exact path in
|
|
23
|
+
its delivery contract. The Engine validates that allowlist and only then stages
|
|
24
|
+
the ignored file. Ordinary `run` work cannot opt itself into that permission.
|
|
25
|
+
|
|
26
|
+
When a requested protected change is blocked, the issue status names the exact
|
|
27
|
+
omitted path and the workflow exits nonzero. The PR can still contain the safe
|
|
28
|
+
files that were successfully delivered; treat it as partial work until an
|
|
29
|
+
approved owner supplies the protected file.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kody-ade/kody-engine",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.622",
|
|
4
4
|
"description": "kody — autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative implementation profiles.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"files": [
|
|
15
15
|
"dist",
|
|
16
16
|
"templates",
|
|
17
|
+
"docs/delivery-boundary.md",
|
|
17
18
|
"kody.config.schema.json"
|
|
18
19
|
],
|
|
19
20
|
"scripts": {
|