@patronage/software-factory 1.0.0-alpha.4 → 1.0.0-alpha.40
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/CONTEXT.md +10 -0
- package/README.md +17 -7
- package/dist/cli.js +12 -0
- package/dist/index.d.ts +3201 -2573
- package/dist/index.js +23055 -14270
- package/dist/review-prompts/security/SKILL.md +1 -0
- package/dist/review-prompts/security/references/javascript-typescript.md +1 -0
- package/dist/schemas.d.ts +664 -1265
- package/dist/schemas.js +911 -762
- package/package.json +15 -16
package/CONTEXT.md
CHANGED
|
@@ -6,12 +6,22 @@ The shared Patronage software factory: typed lifecycle state, proof gates, and o
|
|
|
6
6
|
|
|
7
7
|
## Language
|
|
8
8
|
|
|
9
|
+
### Admission
|
|
10
|
+
|
|
11
|
+
**Candidate**: The exact patch under admission — the `headSha` / `patchId` / `mergeBaseSha` identity every piece of evidence binds to. A GitHub draft pull request is not a Candidate; GitHub's draft boolean is the machine lifecycle authority, and ready-for-review is the Candidate state. Experiment and interactive describe human intent only and create no machine states.
|
|
12
|
+
|
|
13
|
+
**Promotion**: The one transition from a draft pull request into a Candidate. `pr:publish` is the promotion verb. Its composed handoff finishes proof while draft, promotes, then evaluates Candidate demands at the unchanged head. Draft open and synchronize events run no substantive hosted Verify battery; `ready_for_review` starts the complete applicable Candidate pass.
|
|
14
|
+
|
|
9
15
|
### Proof reuse
|
|
10
16
|
|
|
11
17
|
**Proof gate**: A command that emits a typed proof — the self-timed set is `pr:verify`, `pr:review`, `pr:ready`, `boundary:check`, and `factory:closeout`; one execution is a **gate run**. Typed proof files are the source of readiness truth; prose never substitutes.
|
|
12
18
|
|
|
13
19
|
**Proof-reuse gate**: The decision that consumes trusted verification proof and determines whether hosted CI may skip work already performed. Refusing reuse runs the hosted suite; it does not fail the candidate. Defined by ADR 0022. _Avoid_: proof gate (that produces readiness proof rather than reusing it).
|
|
14
20
|
|
|
21
|
+
### Impact
|
|
22
|
+
|
|
23
|
+
**Impact**: The candidate-bound classification of which declared product targets a changed path or lockfile graph can reach. Path impact is opt-in: a target is affected if and only if a valid changed path matches one of its declared globs. A valid path matched by no target is **unsubscribed** and demands no target-scoped work, while remaining explicit in the stamp basis and human summary. A valid path that matches `impact.inert` and no target is **inert-owned**: the stamp records it in `inertPaths`, distinct from `unsubscribedPaths`. A path matching both a target subscription and an inert glob is product-owned and appears in neither list. `pnpm-lock.yaml` is a graph input and is never inert. Shared paths affect every target that subscribes to them. Invalid paths and unreadable or malformed required inputs still fail closed. Impact may withdraw target-scoped work; it never certifies a merge target, whose push-triggered verification stays full. Defined by ADR 0027. _Avoid_: affectedness; implicit filesystem ownership (target `paths` are subscriptions; inert-owned is the explicit `impact.inert` declaration).
|
|
24
|
+
|
|
15
25
|
### Planning intake
|
|
16
26
|
|
|
17
27
|
**Spec**: The single through-line planning artifact — a technical, non-technical, or blended description of the work to be built, produced by `to-spec`. The term supersedes "PRD"; older artifacts titled "PRD:" (e.g. #232) are specs by another name. _Avoid_: PRD (retired), requirements doc.
|
package/README.md
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
The factory admits a pull request from evidence bound to its candidate. It validates policy and proof; it does not schedule workers, choose models, or run reviews. Those are jobs for the harness or operator.
|
|
6
6
|
|
|
7
|
-
Admission is fail closed. A clean-session review and required verification produce typed proof, then readiness decides whether the candidate may proceed. Evidence stays current when the candidate patch is unchanged; the push-triggered Verify workflow covers integration risk on every factory merge target — `main` and the `epic/**` integration branches. When a target goes red, the factory refuses new readiness decisions and authorized arming against that target; candidates armed before the target went red can still land. Epic policy, including review minimums and auto-merge
|
|
7
|
+
Admission is fail closed. A clean-session review and required verification produce typed proof, then readiness decides whether the candidate may proceed. Evidence stays current when the candidate patch is unchanged; the push-triggered Verify workflow covers integration risk on every factory merge target — `main` and the `epic/**` integration branches. When a target goes red, the factory refuses new readiness decisions and authorized arming against that target; candidates armed before the target went red can still land. `pr:ready` arms GitHub native auto-merge for every admitted pull request. It does not arm when the repository does not allow auto-merge, when the pull request carries the `factory:hold` label, or when a boundary wave keeps the candidate attended. Epic policy, including review minimums and the auto-merge decision for its members, lives in the boundary manifest. HQ observes this work; it never blocks a gate.
|
|
8
8
|
|
|
9
9
|
## Develop the package
|
|
10
10
|
|
|
11
|
-
This section and the two below describe the source repository; the paths they mention are not part of the installed npm package. The package lives in the repository pnpm workspace and requires Node 24. From the repository root:
|
|
11
|
+
This section and the two below describe the source repository; the paths they mention are not part of the installed npm package. The package lives in the repository pnpm workspace and requires Node 24.20.0 from `.nvmrc`. Published `engines.node` remains `^24.0.0`. From the repository root:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
14
|
bash scripts/bootstrap-worktree.sh .
|
|
@@ -24,20 +24,24 @@ The package publishes to public npm as `@patronage/software-factory` under MIT.
|
|
|
24
24
|
|
|
25
25
|
Internal architectural packages live under `src/packages/`. Read the package root's `README.md` before editing one. Import only entry points explicitly declared by `dependency-cruiser.config.mjs`; package implementation and fixtures are private. See ADR 0007 (`docs/adr/0007-factory-internal-deep-packages-enforce-module-seams.md` in the source repository).
|
|
26
26
|
|
|
27
|
+
A public export leaves this package only with the supported-consumer, migration and release account in [ADR 0007](https://github.com/patronage/software-factory/blob/main/software-factory/docs/adr/0007-factory-internal-deep-packages-enforce-module-seams.md#public-export-removals). `api:check` reports declaration drift; an open version break window is not removal approval. `src/public-consumer-surface.test.ts` protects the known consumed exports, while a fresh consumer audit and per-export rationale remain review obligations.
|
|
28
|
+
|
|
27
29
|
## Releases
|
|
28
30
|
|
|
29
|
-
This is the release checklist. It lives here and nowhere else; the repository runbook links to it rather than restating it.
|
|
31
|
+
This is the release checklist. It lives here and nowhere else; the repository runbook links to it rather than restating it. Do not let merged work accumulate untagged: merged work that no release-owning boundary carries rides the next attended release.
|
|
30
32
|
|
|
31
|
-
Releases are attended and hand-cut. Nothing in the factory publishes, tags, or releases on its own, and no step below may be automated as a drive-by.
|
|
33
|
+
Releases are attended and hand-cut. Nothing in the factory publishes, tags, or releases on its own, and no step below may be automated as a drive-by. Delivery closeout (`boundary:check --final`, then `factory:closeout` on the epic) is a separate act with a separate owner: it closes the epic and releases nothing. Only a release-owning boundary carries a release, and one issue at a time holds that authority for a given version. A docs-only or non-release-owning runtime boundary closes without a bump and waits for the next attended cut. The admission skill's [closeout reference](../skills/patronage-software-factory-admission/references/epic-closeout.md#delivery-closeout-is-not-a-release) states the same split from the closeout side.
|
|
32
34
|
|
|
33
35
|
The factory family has one version posture (ADR 0026, `docs/adr/0026-factory-family-version-lines-move-in-lockstep.md` in the source repository): `@patronage/factory-ci` moves in lockstep majors with this CLI. From factory-ci's first release in the CLI's current series onward, majors and prerelease series move together while patch and prerelease increments stay independent per package. A consumer pins a factory-ci from the same major/prerelease series as its CLI; there is no compatibility matrix. Until that first lockstep release, factory-ci's published 0.x line is the named pre-adoption state and pairs with any CLI version. `@patronage/alchemy-d1-state` keeps independent SemVer. Lockstep is a rule the maintainer follows when cutting releases, never automation.
|
|
34
36
|
|
|
37
|
+
For a release-owning epic boundary, the terminal oracle runs before the version-bump pull request merges. The candidate it reviews is exact: the merged implementation children plus the open release-owning version-bump PR at its head. Repair its findings inside the same engagement and re-earn the affected evidence before the bump merges. Once the bump merges, the publish, tag, and GitHub release below follow immediately; the six-fact convergence assertion in step 6 stays the post-publication machine readback, never the first correctness review of released behavior. A bump merged before the oracle burns the version number and forces a forward release — that is how alpha.11 needed alpha.12 on 2026-08-09. Nothing enforces this ordering (ADR 0024, `docs/adr/0024-prose-explains-it-never-enforces.md` in the source repository); it is release discipline the maintainer follows.
|
|
38
|
+
|
|
35
39
|
A stacked release train has one terminal release-owning slice. Interior slices do not bump `package.json` or cut a checkpoint unless the boundary explicitly intends a separately published release at that slice: a lower-slice bump consumes the release window before the terminal slice lands, and the train must then advance the version and re-earn its terminal evidence.
|
|
36
40
|
|
|
37
41
|
A stable cut has two phases. Phase 1 is the verified package candidate: steps 1 through 4 below, ending in the attended npm publish, tag, and GitHub release. Phase 2 is post-publication stable-doc convergence: steps 5 and 6, a normal admitted docs PR followed by the read-only convergence assertion from a clean `main`. Stable docs must never claim an unpublished version, so they cannot land in the phase-1 change. Prerelease behavior is unchanged: prerelease notes may land before publish while stable docs keep naming the prior stable version.
|
|
38
42
|
|
|
39
|
-
1. Bump `package.json` to valid SemVer. The assertion derives its expected stable or prerelease channel from the version; it accepts no channel flag.
|
|
40
|
-
2.
|
|
43
|
+
1. Bump `package.json` to valid SemVer. The assertion derives its expected stable or prerelease channel from the version; it accepts no channel flag. Before publishing, prove production HQ accepts this candidate's proof schema. The manifest bump triggers the CI-only `HQ Deploy` workflow because HQ bundles this package's public schemas. From a clean `main`, record `RELEASE_SHA="$(git rev-parse HEAD)"`, find the `HQ Deploy` run with `gh run list --workflow "HQ Deploy" --commit "$RELEASE_SHA"`, and use `gh run watch <run-id> --exit-status`; an older green deployment does not count. One exception is defined: when the version bump merged earlier inside the release boundary and the release-owning PR touches no `HQ Deploy` path, no run can exist at the release SHA. The gate then binds to the most recent merge that modified an `HQ Deploy`-triggering path; that run must be green at its exact SHA, every later merge up to the release SHA must be outside those paths, and the release notes record which SHA satisfied the gate. Then, outside a sandbox, run `psf hq:flush --cwd <candidate-worktree>` against the candidate's retained `pr-verify-proof`. The release may proceed only when the current proof exists, the exact-SHA deployment passed, and the drain reports that proof `delivered` or `duplicate` (or no pending spool because its original delivery already succeeded), with `rejected 0` and no event remaining. This is an attended release-compatibility gate; it does not make HQ authoritative for ordinary admission.
|
|
44
|
+
2. Build and review one pnpm tarball, then publish that exact tarball per the [repository operations runbook](../docs/repository-operations.md#publishing) (attended and hand-cut). Publishing the workspace directory is not allowed because it rebuilds during `prepack` after the artifact review. **Always pass `--tag` explicitly, on every publish, prerelease or stable**: `pnpm publish "$SOFTWARE_FACTORY_TARBALL" --tag next --access public` for a prerelease, `--tag latest` for a stable cut. A filtered directory publish takes pnpm's recursive path, which passes its own `--tag` (defaulting to `latest`) to npm and therefore ignores the `publishConfig.tag: next` pin both factory packages carry; that is how 1.0.0-alpha.6 briefly took `latest` (#658). The pins stay as belt and braces, but they are not the control. Omitting the flag is not a safe failure: it moves `latest`, which the convergence assertion can only report after the fact. The attended token path does not promise an npm provenance attestation; the source SHA and reviewed tarball SRI are its operational provenance.
|
|
41
45
|
3. Cut the `software-factory-vX.Y.Z` tag and push it.
|
|
42
46
|
4. Cut the GitHub release for that tag, with notes covering features, deletions, breaking changes, and closed issues. Mark it as a prerelease exactly when its SemVer version has a prerelease component. When the release changes the profile `schemaVersion`, state it in the notes — the profile schema version is a separate axis from the package version.
|
|
43
47
|
5. Converge the stable docs after publication. Update affected `software-factory-docs/` pages through a normal admitted docs PR. Stable docs must state the current stable version. Prerelease docs may record the candidate and its migration notes, but must not represent it as the current stable release.
|
|
@@ -60,10 +64,16 @@ pnpm exec patronage-factory --help # or: psf --help
|
|
|
60
64
|
|
|
61
65
|
The repository profile declares its admission policy. Operator-local settings and HQ credentials are documented separately, so they do not become committed project configuration.
|
|
62
66
|
|
|
63
|
-
|
|
67
|
+
Generated production workflows may call `psf production:impact --candidate <sha> [--stage <name>] --github-output <path>`. The command resolves demand for each declared impact target from that target's last trusted successful deployment receipt to the checked-out candidate, never from a push's before/after commits, and emits stable demanded/withdrawn target outputs, each target's baseline and delta, and unsubscribed paths. It only withdraws work: a target is withdrawn when its trusted baseline is an ancestor of the candidate and the delta provably misses it, or when the candidate is already behind that baseline (the JSON reads `superseded`); a missing, failed, untrusted, unreachable, or non-ancestor baseline keeps it demanded, and an unusable candidate identity, a missing GitHub Actions run identity, or a profile-scoping refusal leaves every target demanded. After its deploy and health steps, the consumer's job calls `psf production:impact --publish-receipt success|failure --target <name> --candidate <sha>` to write the receipt the next decision reads. The factory owns this decision seam; each consumer owns its deploy jobs, commands, credentials, topology, health policy, and post-deploy convergence/no-op proof. Merge-target Verify remains full and does not consult this command. The [command reference](https://factory.patronage.com/command-reference) defines what makes a receipt trusted.
|
|
68
|
+
|
|
69
|
+
Generated pull-request workflows may call `psf candidate:impact --base <sha> --head <sha> --github-output <path>` to route Candidate verification surfaces. The command evaluates the same profile impact declarations and pnpm dependency graph from the exact base/head identity, diffed from their merge base; it is the candidate-named sibling of `production:impact` and replaces repository-owned path filters, never adds a second matcher. The `head` commit must be the checked-out `HEAD`, and both commits must be reachable (`fetch-depth: 0`). Every doubt path — unreadable identity, malformed or unsupported graph data, an unowned profile change, a working-tree profile that differs from the head commit, or classifier refusal — fails closed and leaves every declared target demanded. `production:impact` decides from deployment receipts, not from a push diff.
|
|
70
|
+
|
|
71
|
+
For factory workflow, install the four canonical skills as the `patronage-software-factory` host plugin (Claude Code, Codex, or Cursor; see [`skills/README.md`](../skills/README.md)). Cloud agents that cannot load host plugins fall back to:
|
|
64
72
|
|
|
65
73
|
```bash
|
|
66
74
|
npx skills add https://github.com/patronage/software-factory -g --all
|
|
67
75
|
```
|
|
68
76
|
|
|
69
77
|
They provide procedure and link back to the documentation site; they are not a second command reference.
|
|
78
|
+
|
|
79
|
+
`assembleReviewPrompt` puts a repository-root `CODING_STANDARDS.md` into the correctness prompt when the file exists and is not blank. It reads the file at the candidate head, not from the working tree, and emits one `coding-standards` section that names the head SHA. A repository without the file gets an unchanged prompt. `pr:review --assemble` writes that factory-owned prompt under `.factory-memory/pr-review-prompt.json`. `pr:review --findings` copies the recorded sections onto the proof when the artifact's patch-id matches.
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { PrPublishFollowUpError, run } from "./index.js";
|
|
3
|
+
//#region src/cli.ts
|
|
4
|
+
try {
|
|
5
|
+
await run(process.argv, import.meta.filename);
|
|
6
|
+
} catch (error) {
|
|
7
|
+
if (error instanceof PrPublishFollowUpError) console.error(JSON.stringify(error.result, null, 2));
|
|
8
|
+
else console.error("\nError:", error instanceof Error ? error.message : String(error));
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export {};
|