code-foundry 1.12.0 → 1.14.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.
- package/.github/CONTRIBUTING.md +7 -6
- package/.github/workflows/draft-enforcement_self-ci.yml +3 -4
- package/.github/workflows/opencode-security_self-ci.yml +2 -1
- package/.github/workflows/validation_self-ci.yml +6 -4
- package/AGENTS.md +6 -5
- package/CHANGELOG.md +14 -0
- package/README.md +7 -6
- package/docs/PERFORMANCE.md +3 -3
- package/docs/README.md +2 -0
- package/docs/WORKFLOWS.md +14 -14
- package/docs/agent-validation.md +94 -0
- package/docs/fleet-rollouts.md +139 -0
- package/package.json +1 -1
- package/src/cli.mjs +7 -0
- package/src/commands/agent-check.mjs +309 -0
- package/src/commands/doctor.mjs +8 -3
- package/src/commands/fleet.mjs +355 -42
- package/src/commands/sync.mjs +11 -6
- package/src/lib/fleet-manifest.mjs +654 -0
package/.github/CONTRIBUTING.md
CHANGED
|
@@ -41,13 +41,14 @@ This repository uses the `direct` workflow. Topic pull requests target `main`.
|
|
|
41
41
|
- Open every ordinary pull request as a draft. Use `gh pr create --draft` or
|
|
42
42
|
set `draft: true` in the GitHub API; never create a ready ordinary pull
|
|
43
43
|
request as a shortcut.
|
|
44
|
-
- Keep ordinary pull requests in draft while
|
|
45
|
-
Draft Guard
|
|
46
|
-
|
|
44
|
+
- Keep ordinary pull requests in draft while preparing them. The generated
|
|
45
|
+
Draft Guard converts ready ordinary pull requests to draft when they are
|
|
46
|
+
opened or reopened, and runner-heavy validation starts only after an
|
|
47
47
|
explicit `ready_for_review` transition.
|
|
48
48
|
- Run local validation and finish review preparation before marking an ordinary
|
|
49
|
-
pull request ready.
|
|
50
|
-
the current head
|
|
49
|
+
pull request ready. Ready pull requests stay ready when new commits arrive,
|
|
50
|
+
and validation reruns for the current head; draft updates allocate no
|
|
51
|
+
validation runner until the pull request is ready.
|
|
51
52
|
- Release Please version pull requests are managed by the Code Foundry release
|
|
52
53
|
workflow; do not manually change their draft state unless the workflow asks.
|
|
53
54
|
|
|
@@ -183,7 +184,7 @@ Keep pull requests focused and reviewable. Include screenshots or recordings for
|
|
|
183
184
|
| Push to a working branch | Draft PR workflow |
|
|
184
185
|
| Push to `main` | Release workflow plus default-branch CodeQL scan; validation ran on the merged PR |
|
|
185
186
|
|
|
186
|
-
Draft pull requests do not start validation. The lightweight Draft Guard
|
|
187
|
+
Draft pull requests do not start validation. The lightweight Draft Guard converts ordinary pull requests opened or reopened while ready back to draft; it never checks out pull-request code and it excludes Release Please version heads, whose release workflow owns their state. Marking a pull request ready for review starts the applicable validation tier, and each new commit on a ready pull request reruns that tier for the current head. Draft updates allocate no validation runner. Converting a pull request to draft runs only the lightweight cancellation control.
|
|
187
188
|
|
|
188
189
|
Pull-request validation keys concurrency by event and pull-request head, so a newer update cancels its superseded run. Scheduled and manual audits use a separate caller pinned to the protected default branch; this prevents caller-selected runtime code from executing with default-branch cache access. Pull-request and scheduled/manual callers use the mode-aware orchestrator, which fans out only the required jobs and concludes with the stable aggregate gate. Main pushes run the default-branch CodeQL lane separately.
|
|
189
190
|
|
|
@@ -8,7 +8,6 @@ on:
|
|
|
8
8
|
types:
|
|
9
9
|
- opened
|
|
10
10
|
- reopened
|
|
11
|
-
- synchronize
|
|
12
11
|
|
|
13
12
|
permissions:
|
|
14
13
|
pull-requests: write
|
|
@@ -55,8 +54,8 @@ jobs:
|
|
|
55
54
|
;;
|
|
56
55
|
esac
|
|
57
56
|
|
|
58
|
-
# A newer state transition
|
|
59
|
-
#
|
|
57
|
+
# A newer state transition superseded this event. Do not undo a
|
|
58
|
+
# user's later explicit readiness decision with a stale event.
|
|
60
59
|
if [ "$head_sha" != "$EVENT_HEAD_SHA" ] || [ "$updated_at" != "$EVENT_UPDATED_AT" ]; then
|
|
61
60
|
echo 'A newer pull-request state or head commit superseded this draft-guard event; leaving the current state unchanged.'
|
|
62
61
|
exit 0
|
|
@@ -76,4 +75,4 @@ jobs:
|
|
|
76
75
|
"repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER" \
|
|
77
76
|
-F draft=true \
|
|
78
77
|
--silent >/dev/null
|
|
79
|
-
echo "Converted ordinary pull request #$PR_NUMBER to draft;
|
|
78
|
+
echo "Converted ordinary pull request #$PR_NUMBER to draft; validation waits for ready_for_review."
|
|
@@ -5,6 +5,7 @@ on:
|
|
|
5
5
|
branches: [main, staging]
|
|
6
6
|
types:
|
|
7
7
|
- ready_for_review
|
|
8
|
+
- synchronize
|
|
8
9
|
workflow_dispatch:
|
|
9
10
|
|
|
10
11
|
permissions:
|
|
@@ -13,7 +14,7 @@ permissions:
|
|
|
13
14
|
jobs:
|
|
14
15
|
detect:
|
|
15
16
|
name: OpenCode Security / Detect
|
|
16
|
-
if: vars.CI_BILLING_PAUSED != 'true'
|
|
17
|
+
if: vars.CI_BILLING_PAUSED != 'true' && (github.event_name == 'workflow_dispatch' || github.event.pull_request.draft == false)
|
|
17
18
|
runs-on: ubuntu-slim
|
|
18
19
|
outputs:
|
|
19
20
|
enabled: ${{ steps.detect.outputs.enabled }}
|
|
@@ -7,6 +7,7 @@ on:
|
|
|
7
7
|
branches: [main, staging]
|
|
8
8
|
types:
|
|
9
9
|
- ready_for_review
|
|
10
|
+
- synchronize
|
|
10
11
|
|
|
11
12
|
# Default every caller job to no repository permissions. Individual jobs grant
|
|
12
13
|
# only the scopes their own validation path consumes.
|
|
@@ -20,9 +21,10 @@ concurrency:
|
|
|
20
21
|
jobs:
|
|
21
22
|
mode:
|
|
22
23
|
name: Mode
|
|
23
|
-
# The mode classifier is only needed for pull requests. Main pushes
|
|
24
|
-
# the dedicated default-branch CodeQL lane below
|
|
25
|
-
|
|
24
|
+
# The mode classifier is only needed for ready pull requests. Main pushes
|
|
25
|
+
# use the dedicated default-branch CodeQL lane below; draft updates do not
|
|
26
|
+
# allocate a validation runner.
|
|
27
|
+
if: vars.CI_BILLING_PAUSED != 'true' && github.event_name == 'pull_request' && github.event.pull_request.draft == false
|
|
26
28
|
runs-on: ubuntu-slim
|
|
27
29
|
timeout-minutes: 10
|
|
28
30
|
permissions:
|
|
@@ -62,7 +64,7 @@ jobs:
|
|
|
62
64
|
validation:
|
|
63
65
|
name: Validation
|
|
64
66
|
needs: mode
|
|
65
|
-
if: vars.CI_BILLING_PAUSED != 'true' && github.event_name == 'pull_request'
|
|
67
|
+
if: vars.CI_BILLING_PAUSED != 'true' && github.event_name == 'pull_request' && github.event.pull_request.draft == false
|
|
66
68
|
# Reusable workflows can only maintain or reduce the caller job's scopes.
|
|
67
69
|
# The audit tier needs security-events: write for CodeQL uploads.
|
|
68
70
|
permissions:
|
package/AGENTS.md
CHANGED
|
@@ -103,13 +103,14 @@ This repository uses the `direct` workflow. Topic pull requests target `main`.
|
|
|
103
103
|
- Open every ordinary pull request as a draft. Use `gh pr create --draft` or
|
|
104
104
|
set `draft: true` in the GitHub API; never create a ready ordinary pull
|
|
105
105
|
request as a shortcut.
|
|
106
|
-
- Keep ordinary pull requests in draft while
|
|
107
|
-
Draft Guard
|
|
108
|
-
|
|
106
|
+
- Keep ordinary pull requests in draft while preparing them. The generated
|
|
107
|
+
Draft Guard converts ready ordinary pull requests to draft when they are
|
|
108
|
+
opened or reopened, and runner-heavy validation starts only after an
|
|
109
109
|
explicit `ready_for_review` transition.
|
|
110
110
|
- Run local validation and finish review preparation before marking an ordinary
|
|
111
|
-
pull request ready.
|
|
112
|
-
the current head
|
|
111
|
+
pull request ready. Ready pull requests stay ready when new commits arrive,
|
|
112
|
+
and validation reruns for the current head; draft updates allocate no
|
|
113
|
+
validation runner until the pull request is ready.
|
|
113
114
|
- This contract is mandatory for every agent scope. Nested `AGENTS.md` files
|
|
114
115
|
may add stricter rules but must not weaken or replace it.
|
|
115
116
|
- Release Please version pull requests are managed by the Code Foundry release
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.14.0](https://github.com/0xPlayerOne/code-foundry/compare/v1.13.0...v1.14.0) (2026-09-09)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **cli:** add shared validation plans and agent check evidence ([#538](https://github.com/0xPlayerOne/code-foundry/issues/538)) ([95af9ed](https://github.com/0xPlayerOne/code-foundry/commit/95af9ed42682ff3ed1dc74609ea4628d0c95a799))
|
|
9
|
+
|
|
10
|
+
## [1.13.0](https://github.com/0xPlayerOne/code-foundry/compare/v1.12.0...v1.13.0) (2026-09-09)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* **fleet:** add declared inventory and resumable canary rollouts ([#536](https://github.com/0xPlayerOne/code-foundry/issues/536)) ([6aa86d4](https://github.com/0xPlayerOne/code-foundry/commit/6aa86d4cd85cdbd4041c70d8c01d8e351e21fc0b))
|
|
16
|
+
|
|
3
17
|
## [1.12.0](https://github.com/0xPlayerOne/code-foundry/compare/v1.11.0...v1.12.0) (2026-09-09)
|
|
4
18
|
|
|
5
19
|
|
package/README.md
CHANGED
|
@@ -76,12 +76,13 @@ The standard workflow triggers are:
|
|
|
76
76
|
|
|
77
77
|
Automated feature/fix and staging-promotion pull requests open as drafts.
|
|
78
78
|
The trusted Draft Guard is a fallback for manually created or reopened ready
|
|
79
|
-
PRs
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
ready
|
|
84
|
-
cancellation control. Scheduled and manually
|
|
79
|
+
PRs: it converts them to drafts without checking out PR code. It verifies the
|
|
80
|
+
event head and update timestamp before changing state, and excludes Release
|
|
81
|
+
Please version PRs whose release workflow owns readiness. Pull-request
|
|
82
|
+
validation runs on the ready-for-review transition and on new commits while a
|
|
83
|
+
PR remains ready; draft updates allocate no validation runner. Converting a PR
|
|
84
|
+
to draft runs only the lightweight cancellation control. Scheduled and manually
|
|
85
|
+
dispatched audits are unaffected.
|
|
85
86
|
|
|
86
87
|
Jobs are language-aware and skip irrelevant setup inside the applicable
|
|
87
88
|
aggregate checks. TypeScript uses Oxlint, Oxfmt, and Bun's native
|
package/docs/PERFORMANCE.md
CHANGED
|
@@ -15,9 +15,9 @@ belong to the run that produced them, not the source tree.
|
|
|
15
15
|
| Format, lint, type-check, and build | 15 s | Bound the local CI feedback loop |
|
|
16
16
|
| Runtime dependencies | 0 | Keep the installed CLI dependency-free |
|
|
17
17
|
| Development dependencies | 4 | Prevent unreviewed toolchain growth |
|
|
18
|
-
| Packed artifact |
|
|
19
|
-
| Unpacked artifact |
|
|
20
|
-
| Packed files |
|
|
18
|
+
| Packed artifact | 210 kB | Bound registry transfer and install cost |
|
|
19
|
+
| Unpacked artifact | 820 kB | Bound installed footprint |
|
|
20
|
+
| Packed files | 92 | Detect accidental release contents |
|
|
21
21
|
|
|
22
22
|
The performance workflow disables build-cache reads and writes for this task.
|
|
23
23
|
That makes timing comparisons independent of a warm protected-branch cache and
|
package/docs/README.md
CHANGED
|
@@ -14,6 +14,8 @@ its own names, environments, and deployment details.
|
|
|
14
14
|
- [Caching and remote caching](CACHING.md)
|
|
15
15
|
- [Performance budgets and baselines](PERFORMANCE.md)
|
|
16
16
|
- [Required capabilities and task evidence](required-capabilities.md)
|
|
17
|
+
- [Agent-facing validation commands](agent-validation.md)
|
|
18
|
+
- [Declarative fleet inventory and staged rollouts](fleet-rollouts.md)
|
|
17
19
|
|
|
18
20
|
## Repository-specific documentation
|
|
19
21
|
|
package/docs/WORKFLOWS.md
CHANGED
|
@@ -15,19 +15,19 @@ pull_request:
|
|
|
15
15
|
# direct topology: branches: [main]
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
The generated validation caller listens for `ready_for_review` and
|
|
19
|
-
`
|
|
20
|
-
validation runner; main pushes run only the default-branch
|
|
21
|
-
full validation remains pull-request-only.
|
|
22
|
-
|
|
23
|
-
`
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
pull
|
|
30
|
-
request
|
|
18
|
+
The generated validation caller listens for `ready_for_review` and
|
|
19
|
+
`synchronize`. Its jobs require the pull request to remain ready, so draft
|
|
20
|
+
updates allocate no validation runner; main pushes run only the default-branch
|
|
21
|
+
CodeQL lane, while full validation remains pull-request-only. A separate
|
|
22
|
+
lightweight Draft Guard runs from the trusted base branch on `opened` and
|
|
23
|
+
`reopened`; it converts ordinary ready pull requests back to draft without
|
|
24
|
+
checking out pull-request code. It rechecks the current head and update
|
|
25
|
+
timestamp before mutating state, so a stale event cannot undo a later draft or
|
|
26
|
+
ready transition. Release Please version heads are excluded because the
|
|
27
|
+
release workflow owns their state. A separate draft-control caller listens for
|
|
28
|
+
`converted_to_draft` and cancels queued or running pull-request workflows.
|
|
29
|
+
Marking a pull request ready starts validation, and each new commit on a ready
|
|
30
|
+
pull request starts it again for the current head.
|
|
31
31
|
|
|
32
32
|
The separate `validation-audit.yml` caller is pinned to the configured released
|
|
33
33
|
runtime and handles scheduled and manual audits:
|
|
@@ -108,7 +108,7 @@ opt in or out without a code change.
|
|
|
108
108
|
| Security | Profile, audits, and public-only Dependency Review |
|
|
109
109
|
| CodeQL | GitHub-native code scanning, kept separate from CI |
|
|
110
110
|
| Draft PR | Create/update development pull requests |
|
|
111
|
-
| Draft Guard | Keep ordinary PRs draft until `ready_for_review`
|
|
111
|
+
| Draft Guard | Keep opened/reopened ordinary PRs draft until `ready_for_review` |
|
|
112
112
|
| Release PR | Promote `staging` into `main` (staging-release topology only) |
|
|
113
113
|
| Release | Release Please, GitHub release, and optional npm publication |
|
|
114
114
|
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Agent-facing validation commands
|
|
2
|
+
|
|
3
|
+
The public CLI now exposes a stable plan/check interface using the same discovery,
|
|
4
|
+
required-capability policy, ecosystem executor, and task receipts as reusable CI.
|
|
5
|
+
|
|
6
|
+
```sh
|
|
7
|
+
code-foundry plan --changed --base origin/main --json
|
|
8
|
+
code-foundry check --tier fast --json
|
|
9
|
+
code-foundry check --tier audit --json
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Both commands accept `--target PATH`. Use the Code Foundry version pinned by the
|
|
13
|
+
repository, not an unreviewed floating installation. `plan` executes discovery
|
|
14
|
+
only: it does not install dependencies, run project checks, modify source files,
|
|
15
|
+
or emit skip-receipt files. Required entrypoints are validated across the complete
|
|
16
|
+
task set, including tasks deferred from the selected local tier.
|
|
17
|
+
|
|
18
|
+
## Tiers and change awareness
|
|
19
|
+
|
|
20
|
+
`fast` selects formatting, linting, type checking, build, unit tests, and performance.
|
|
21
|
+
`audit` adds integration, E2E, and smoke tests. Ecosystem commands and applicability
|
|
22
|
+
come from the shared runtime; the CLI does not invent alternate test commands.
|
|
23
|
+
Repository-owned scripts remain authoritative. Missing required tasks fail
|
|
24
|
+
planning instead of returning a misleading successful subset.
|
|
25
|
+
|
|
26
|
+
`--changed` includes paths changed from the selected base, staged changes,
|
|
27
|
+
unstaged changes, and untracked files. Committed paths use the merge-base with
|
|
28
|
+
that ref, so an independently advanced base branch does not make base-only
|
|
29
|
+
changes look like head changes. `--base` defaults to HEAD and requires `--changed`.
|
|
30
|
+
Invalid or unavailable base revisions fail rather than being treated as no changes.
|
|
31
|
+
Paths use Git's NUL-separated format, preserving whitespace and unusual filenames.
|
|
32
|
+
Generated `.code-foundry/` evidence is excluded from change annotations. Change awareness is **annotation-only**: without a verified dependency
|
|
33
|
+
graph it does not skip required tasks or assume a documentation change cannot
|
|
34
|
+
affect a custom command.
|
|
35
|
+
|
|
36
|
+
Local tiers are not a replacement for the complete GitHub Validation / Gate.
|
|
37
|
+
Security scans, CodeQL, release-diff policy where applicable, protected-environment
|
|
38
|
+
checks, and required reviews remain separate. Every plan/result explicitly marks
|
|
39
|
+
remote validation as required. A fast result also names deferred local tasks.
|
|
40
|
+
A local audit result is not permission to mark a PR ready or merge it.
|
|
41
|
+
|
|
42
|
+
## Execution and evidence
|
|
43
|
+
|
|
44
|
+
Install the repository's locked dependencies through its normal setup process
|
|
45
|
+
before running checks. This CLI does not add an implicit install step or grant
|
|
46
|
+
credentials. It runs trusted repository scripts in the existing environment;
|
|
47
|
+
those scripts are not sandboxed and retain their normal tool/network behavior.
|
|
48
|
+
The formatter/runtime's existing semantics are unchanged: a configured command
|
|
49
|
+
that rewrites files still rewrites files. Prefer check-only scripts in CI.
|
|
50
|
+
|
|
51
|
+
Task stdout/stderr goes to stderr, keeping `--json` stdout parseable. Each selected
|
|
52
|
+
applicable task runs through the public runtime. A zero exit without a fresh,
|
|
53
|
+
matching, successful task receipt fails. A failed task blocks remaining applicable
|
|
54
|
+
tasks; optional inapplicable tasks are reported as skipped. An entirely skipped
|
|
55
|
+
check is labeled `skipped`, never `passed`.
|
|
56
|
+
|
|
57
|
+
A run stores `.code-foundry/agent-results/check-*/summary.json` and snapshots of
|
|
58
|
+
its task receipts. The result includes the source commit, dirty-tree indication,
|
|
59
|
+
selected/deferred tasks, reasons, exit codes, signals, receipt paths, and repository
|
|
60
|
+
artifact paths such as coverage or browser evidence. HEAD identifies the base
|
|
61
|
+
commit; a dirty working tree is not a cryptographically identified immutable
|
|
62
|
+
source snapshot. Reports are local evidence, not signed provenance.
|
|
63
|
+
|
|
64
|
+
The aggregate and task receipts are retained per run so later checks do not
|
|
65
|
+
overwrite the earlier JSON evidence. Artifact paths inside receipts point to
|
|
66
|
+
repository-owned files and may be overwritten by subsequent test runs; copy them
|
|
67
|
+
into a CI artifact for long-term retention. Do not upload the whole hidden
|
|
68
|
+
repository tree or secrets. The CLI neither captures environment variables into
|
|
69
|
+
reports nor grants publish/merge/deploy access.
|
|
70
|
+
|
|
71
|
+
An exclusive local `agent-results/active.lock` prevents overlapping agent checks
|
|
72
|
+
from confusing receipts. After a killed process, inspect the checkout and confirm
|
|
73
|
+
there is no active check before manually removing a stale lock. Normal completion
|
|
74
|
+
and failures clean the lock. This is a local CLI lock, not a distributed lock
|
|
75
|
+
against every other tool writing into the repository.
|
|
76
|
+
|
|
77
|
+
`--timeout SECONDS` bounds each check subprocess (default 600, range 1–3600).
|
|
78
|
+
A timeout or missing receipt fails. Project scripts remain responsible for
|
|
79
|
+
cleaning up their own servers and subprocesses. Plans do not accept an execution
|
|
80
|
+
timeout. Unknown, duplicate, or ignored arguments fail rather than silently alter
|
|
81
|
+
validation behavior.
|
|
82
|
+
|
|
83
|
+
## Integration and tests
|
|
84
|
+
|
|
85
|
+
This change depends on the required-capabilities/task-evidence runtime change.
|
|
86
|
+
It deliberately imports shared policy instead of maintaining a competing copy.
|
|
87
|
+
Merge that prerequisite before this CLI change and retain `runtime-core.mjs` when
|
|
88
|
+
vendoring the runtime.
|
|
89
|
+
|
|
90
|
+
Run `node --test test/agent-check.test.mjs`. Tests exercise real Git change
|
|
91
|
+
inspection and the actual policy/evidence wrapper with a deterministic ecosystem
|
|
92
|
+
executor, including read-only planning, required deferred tasks, failed commands,
|
|
93
|
+
stale evidence, receipt snapshots, locking, and separation of JSON from task logs.
|
|
94
|
+
Full ecosystem dependencies and GitHub-side checks still need their own CI run.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Declarative fleet inventory and staged rollouts
|
|
2
|
+
|
|
3
|
+
Place `code-foundry-fleet.json` in the directory passed to `--root`. Its presence
|
|
4
|
+
opts that fleet into inventory-based discovery and controlled upgrades, without
|
|
5
|
+
changing legacy directory discovery for existing users.
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"schemaVersion": 1,
|
|
10
|
+
"cohorts": ["canary", "applications"],
|
|
11
|
+
"repositories": [
|
|
12
|
+
{
|
|
13
|
+
"repository": "owner/package-canary",
|
|
14
|
+
"path": "packages/package-canary",
|
|
15
|
+
"cohort": "canary",
|
|
16
|
+
"profile": "published-package",
|
|
17
|
+
"expected": { "git_workflow": "direct" },
|
|
18
|
+
"requiredCapabilities": ["unit", "performance"],
|
|
19
|
+
"validation": [
|
|
20
|
+
["bun", "install", "--frozen-lockfile"],
|
|
21
|
+
["bun", "run", "test:unit"],
|
|
22
|
+
["bun", "run", "test:consumer"],
|
|
23
|
+
["bun", "run", "performance:check"]
|
|
24
|
+
],
|
|
25
|
+
"requiredChecks": ["Validation / Gate"]
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"repository": "owner/application",
|
|
29
|
+
"path": "applications/application",
|
|
30
|
+
"cohort": "applications",
|
|
31
|
+
"validation": [
|
|
32
|
+
["bun", "install", "--frozen-lockfile"],
|
|
33
|
+
["bun", "run", "type-check"],
|
|
34
|
+
["bun", "run", "test:unit"]
|
|
35
|
+
],
|
|
36
|
+
"requiredChecks": ["Validation / Gate"]
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Repository names in the example are placeholders. Populate the actual fleet
|
|
43
|
+
before use. Paths are relative to the manifest, may be arbitrarily nested, and
|
|
44
|
+
must not escape through `..`, absolute paths, or symlinks. Missing checkouts and
|
|
45
|
+
origin mismatches remain visible as blocked inventory entries rather than silently
|
|
46
|
+
disappearing. There is no automatic clone or repository-settings mutation.
|
|
47
|
+
|
|
48
|
+
`profile` is a descriptive inventory annotation; it does not install tools or
|
|
49
|
+
activate a quality profile. `expected` maps scalar `.github/code-foundry.yml` keys
|
|
50
|
+
to desired values; `requiredCapabilities` audits declarations in that same file.
|
|
51
|
+
The runtime-upgrade operation does not silently author missing capability policy.
|
|
52
|
+
Adopt those requirements in consumer repositories before requiring them here.
|
|
53
|
+
|
|
54
|
+
## Commands
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
code-foundry fleet status --root /path/to/fleet
|
|
58
|
+
code-foundry fleet upgrade --root /path/to/fleet --dry-run
|
|
59
|
+
code-foundry fleet upgrade --root /path/to/fleet --create-pr
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Run from the intended released Code Foundry installation/checkout. The existing
|
|
63
|
+
source-version guard still rejects mismatched `--version` requests. Manifest mode
|
|
64
|
+
requires `--create-pr` or `--dry-run` and never syncs original checkouts in place.
|
|
65
|
+
`--force` does not bypass dirty-tree safety in manifest mode. Dry-run reports
|
|
66
|
+
inventory, target version, and configuration drift without network calls, running
|
|
67
|
+
consumer commands, or modifying files. Status likewise audits local facts; it does
|
|
68
|
+
not pretend to verify remote branch protection or environment settings.
|
|
69
|
+
|
|
70
|
+
The first incomplete cohort is the only cohort allowed to create PRs. All
|
|
71
|
+
non-excepted members of each earlier cohort must have a matching managed upgrade
|
|
72
|
+
PR that is merged, successful explicitly named required checks on its head SHA,
|
|
73
|
+
no still-pending/failed checks, and the target runtime/configuration still present
|
|
74
|
+
on its current base branch. Neutral/skipped required checks do not qualify.
|
|
75
|
+
Unknown, inaccessible, closed-without-merge, stale, or failed evidence does not
|
|
76
|
+
unlock subsequent cohorts. One local validation failure stops remaining work.
|
|
77
|
+
|
|
78
|
+
Each repository must supply explicit validation argv arrays. Include locked
|
|
79
|
+
installation, application checks, and genuine consumer compatibility tests where
|
|
80
|
+
relevant. No shell splitting is used. Commands run in an isolated detached
|
|
81
|
+
worktree, have bounded execution time, and must not rewrite the candidate source.
|
|
82
|
+
Validation is not a security sandbox: commands run as the invoking user with its
|
|
83
|
+
inherited environment and network access. Treat the manifest and every validation
|
|
84
|
+
command as trusted code; do not use this feature with unreviewed manifests or
|
|
85
|
+
credentials that the checks should not access.
|
|
86
|
+
Only files changed by Code Foundry sync are staged; generated test evidence and
|
|
87
|
+
other untracked files are not swept into the commit. A commit-hook change to the
|
|
88
|
+
validated Git tree is rejected before publishing.
|
|
89
|
+
|
|
90
|
+
This implementation does not create an automatic scheduler, mark PRs ready,
|
|
91
|
+
merge PRs, lower checks, or bypass review. After reviewing and validating canaries,
|
|
92
|
+
merge their PRs normally and run the fleet command again to advance the cohort.
|
|
93
|
+
A repository already at the target version with no managed PR does not establish
|
|
94
|
+
canary evidence; choose a real upgrade canary rather than treating an empty diff
|
|
95
|
+
as successful rollout validation.
|
|
96
|
+
|
|
97
|
+
## Resuming and intentional exceptions
|
|
98
|
+
|
|
99
|
+
The target version and complete repository policy produce a deterministic branch
|
|
100
|
+
and PR marker. Repeated runs return an existing matching open PR instead of
|
|
101
|
+
creating duplicates. If push succeeded but PR creation failed, the next run
|
|
102
|
+
recognizes the managed commit and recorded tree identity, reruns consumer
|
|
103
|
+
validation, and creates the missing **draft** PR without force-pushing. Unknown
|
|
104
|
+
branches or commits with mismatched tree markers are preserved and blocked for
|
|
105
|
+
manual review. Local managed refs preserve committed work after a failed push.
|
|
106
|
+
The marker is an ownership/recovery guard, not a cryptographic signature.
|
|
107
|
+
|
|
108
|
+
PR creation is draft-first in both manifest and legacy discovery modes. A PR that
|
|
109
|
+
a human has already made ready is not silently converted back or modified.
|
|
110
|
+
|
|
111
|
+
An entry may include a reviewed time-limited exception:
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{ "exception": { "reason": "Pending consumer compatibility work", "expires": "2026-10-01" } }
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Exceptions appear explicitly in inventory/rollout output. Expired/invalid dates
|
|
118
|
+
fail parsing. The command's existing `--exclude` flag is also honored. Excluding
|
|
119
|
+
all canaries never satisfies a canary gate or unlocks later cohorts. Update the
|
|
120
|
+
manifest deliberately when cohort membership or compatibility policy changes.
|
|
121
|
+
|
|
122
|
+
## Evidence and tests
|
|
123
|
+
|
|
124
|
+
Upgrade output is schema-versioned JSON with target version, aggregate status,
|
|
125
|
+
per-repository cohort/status, PR link, and local validation command exit statuses.
|
|
126
|
+
Failed command output is not copied into reports, avoiding accidental credentials
|
|
127
|
+
in logs; reproduce the declared command locally for full debugging output. A
|
|
128
|
+
failed rollout returns a nonzero exit status. Pending PRs are not failures and do
|
|
129
|
+
not grant permission to advance a cohort. Worktree cleanup failures preserve the
|
|
130
|
+
isolated path and report it rather than deleting unknown paths.
|
|
131
|
+
|
|
132
|
+
`node --test test/fleet-manifest.test.mjs` includes actual local Git repositories,
|
|
133
|
+
bare remotes, isolated worktrees, validation failure, orphan-branch recovery,
|
|
134
|
+
clean-original preservation, and canary advancement. Only GitHub responses are
|
|
135
|
+
fixture-backed; no real fleet repositories or remote PRs are modified by tests.
|
|
136
|
+
|
|
137
|
+
GitHub CLI contracts:
|
|
138
|
+
https://cli.github.com/manual/gh_pr_list
|
|
139
|
+
https://cli.github.com/manual/gh_pr_create
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "code-foundry",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"description": "A fast, language-aware repository factory for agent-ready workflows, testing, security, and release automation.",
|
|
5
5
|
"homepage": "https://github.com/0xPlayerOne/code-foundry#readme",
|
|
6
6
|
"bugs": {
|
package/src/cli.mjs
CHANGED
|
@@ -16,6 +16,8 @@ Usage:
|
|
|
16
16
|
npx code-foundry init [--target PATH]
|
|
17
17
|
npx code-foundry sync [--target PATH]
|
|
18
18
|
npx code-foundry doctor [--target PATH]
|
|
19
|
+
npx code-foundry plan [--target PATH] [--tier fast|audit] [--changed] [--base REF] [--json]
|
|
20
|
+
npx code-foundry check [--target PATH] [--tier fast|audit] [--changed] [--base REF] [--timeout SECONDS] [--json]
|
|
19
21
|
npx code-foundry ci pause|resume|status [--target PATH]
|
|
20
22
|
npx code-foundry release reconcile [--github] [--base BRANCH] [--head BRANCH]
|
|
21
23
|
npx code-foundry release hook --tag TAG --workflow WORKFLOW
|
|
@@ -124,6 +126,11 @@ function parseArgs(argv) {
|
|
|
124
126
|
}
|
|
125
127
|
|
|
126
128
|
async function main() {
|
|
129
|
+
if (['plan', 'check'].includes(process.argv[2])) {
|
|
130
|
+
const { agentCommand } = await import('./commands/agent-check.mjs')
|
|
131
|
+
process.exitCode = agentCommand(process.argv.slice(2))
|
|
132
|
+
return
|
|
133
|
+
}
|
|
127
134
|
const { command, options } = parseArgs(process.argv.slice(2))
|
|
128
135
|
const target = resolve(options.target)
|
|
129
136
|
|