@patronage/software-factory 1.0.0-alpha.3 → 1.0.0-alpha.31
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 +16 -6
- package/dist/cli.js +12 -0
- package/dist/index.d.ts +2127 -1767
- package/dist/index.js +17359 -13069
- 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 +659 -1313
- package/dist/schemas.js +855 -725
- package/package.json +16 -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
|
@@ -8,7 +8,7 @@ Admission is fail closed. A clean-session review and required verification produ
|
|
|
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 --before <sha> --after <sha> --github-output <path>`. The command recomputes the profile's opt-in impact subscriptions from those exact real commits and emits stable demanded/withdrawn target outputs, the changed-file decision basis, and unsubscribed paths. It only withdraws work: missing, zero, malformed, unreachable, non-ancestral, or otherwise unclassifiable identities leave every known target demanded. The factory owns this decision seam; each consumer owns its deploy jobs, commands, credentials, topology, and post-deploy convergence/no-op proof. Merge-target Verify remains full and does not consult this command.
|
|
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` keeps its merge-push `before`/`after` contract unchanged.
|
|
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 {};
|