persona-harness 0.8.21 → 0.8.22
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/dist/cli/authority-command-surface.js +7 -2
- package/dist/cli/authority-command-surface.js.map +1 -1
- package/docs/current/release/consumer-authority-v0822-acceptance.json +1215 -0
- package/docs/current/release/history.md +7 -5
- package/docs/current/release/project-finish-attestation-verifier.md +5 -1
- package/docs/current/release/v0.8.21-release-notes.md +8 -10
- package/docs/current/release/v0.8.22-release-notes.md +28 -0
- package/package.json +3 -1
- package/packages/shared-skills/package.json +1 -1
- package/scripts/consumer-authority-v0822-acceptance-schema.d.mts +40 -0
- package/scripts/consumer-authority-v0822-acceptance-schema.mjs +83 -0
- package/scripts/preflight-consumer-authority-external-artifact-transport.mjs +2 -2
- package/scripts/preflight-consumer-authority-external-attestation.mjs +2 -2
|
@@ -9,13 +9,15 @@ version/package chronology, use
|
|
|
9
9
|
[`docs/releases/README.md`](../../releases/README.md) and
|
|
10
10
|
[`docs/releases/package-index.md`](../../releases/package-index.md).
|
|
11
11
|
|
|
12
|
-
## Current 0.8.
|
|
12
|
+
## Current 0.8.22 Package Authority
|
|
13
13
|
|
|
14
|
-
The current unpublished package authority is 0.8.
|
|
15
|
-
lockfile, private shared-skills package, and
|
|
16
|
-
exactly. The published 0.8.
|
|
14
|
+
The current unpublished package authority is 0.8.22. Its root package,
|
|
15
|
+
lockfile, private shared-skills package, and v0822 acceptance record must agree
|
|
16
|
+
exactly. The published 0.8.21 release is immutable historical evidence only
|
|
17
17
|
and must not be retagged, rerun, or published.
|
|
18
|
-
The package-visible read-only `ph authority verify` surface
|
|
18
|
+
The package-visible read-only `ph authority verify` surface accepts canonical
|
|
19
|
+
`sha256:<64hex>` or an exact raw SHA-256 hex digest, normalizing either form
|
|
20
|
+
before the same no-follow archive boundary. It never fetches,
|
|
19
21
|
persists, consumes, finishes, or replays authority. Its `.2` result exposes a
|
|
20
22
|
finite `sourceReason` only alongside `source-mismatch`; unavailable Sigstore
|
|
21
23
|
trust remains a fixed blocked result rather than a trust claim.
|
|
@@ -92,7 +92,7 @@ caller that already holds one original archive:
|
|
|
92
92
|
```text
|
|
93
93
|
ph authority verify [owner/repository] --archive <original-archive> \
|
|
94
94
|
--artifact-id <id> --run-id <run-id> --source-head <commit> \
|
|
95
|
-
--artifact-digest sha256:<digest> --json
|
|
95
|
+
--artifact-digest <sha256:<digest>|64hex> --json
|
|
96
96
|
```
|
|
97
97
|
|
|
98
98
|
The command requires all four tuple fields, the current enrolled source and
|
|
@@ -102,6 +102,10 @@ and checks its digest before invoking the existing verifier. It never reads a
|
|
|
102
102
|
GitHub credential, fetches an artifact, writes the authority store, consumes
|
|
103
103
|
authority, runs Finish, or performs replay.
|
|
104
104
|
|
|
105
|
+
The digest is canonicalized to lowercase `sha256:<64hex>`. Callers may supply
|
|
106
|
+
that canonical form or an exact raw 64-character SHA-256 hex digest; every
|
|
107
|
+
other form remains blocked before archive verification.
|
|
108
|
+
|
|
105
109
|
Its public result is `consumer-authority-verify.2` with fixed fields for
|
|
106
110
|
eligibility, consumption state, bounded reason, schema, source-fallback state,
|
|
107
111
|
and terminal state. Only `source-mismatch` includes a finite nonreflective
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
# v0.8.21 Release Notes
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Historical package authority
|
|
4
4
|
|
|
5
|
-
`0.8.21`
|
|
5
|
+
`0.8.21` was published as an immutable stable release. Its root package,
|
|
6
6
|
lockfile, private shared-skills package, and
|
|
7
|
-
`consumer-authority-v0821-acceptance.json`
|
|
8
|
-
|
|
9
|
-
or a replacement publish.
|
|
7
|
+
`consumer-authority-v0821-acceptance.json` remain historical release evidence;
|
|
8
|
+
they cannot authorize a later candidate or a second publish.
|
|
10
9
|
|
|
11
10
|
## Portable repair source identity
|
|
12
11
|
|
|
@@ -22,9 +21,8 @@ The exclusion is intentionally narrow. A reviewed
|
|
|
22
21
|
all other tracked or untracked source stay in the signed identity and continue
|
|
23
22
|
to drift or fail closed as before.
|
|
24
23
|
|
|
25
|
-
##
|
|
24
|
+
## Historical boundary
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
trigger for #338; fixture and V4 observations remain separately governed.
|
|
26
|
+
The release completed through protected integration, a stable GitHub Release,
|
|
27
|
+
and one npm `latest` publication. Fixture and V4 observations remain separate
|
|
28
|
+
evidence paths and do not alter this immutable release history.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# v0.8.22 Release Notes
|
|
2
|
+
|
|
3
|
+
## Current package authority
|
|
4
|
+
|
|
5
|
+
`0.8.22` is the current unpublished package authority. The root package,
|
|
6
|
+
lockfile, private shared-skills package, and
|
|
7
|
+
`consumer-authority-v0822-acceptance.json` bind the same version. Published
|
|
8
|
+
`0.8.21` is immutable historical evidence and cannot authorize this candidate
|
|
9
|
+
or a replacement publish.
|
|
10
|
+
|
|
11
|
+
## Authority verify digest normalization
|
|
12
|
+
|
|
13
|
+
The installed read-only `ph authority verify` command accepts either its
|
|
14
|
+
canonical `sha256:<64hex>` archive digest or an exact raw 64-character
|
|
15
|
+
SHA-256 hex value. Raw input is normalized before archive comparison, so both
|
|
16
|
+
forms bind the same tuple and retain the existing no-follow, enrollment,
|
|
17
|
+
source, crypto, and non-consuming boundaries.
|
|
18
|
+
|
|
19
|
+
Partial tuples, invalid sizes or characters, unsupported algorithms, duplicate
|
|
20
|
+
flags, symlink archives, and tuple mismatches still block before verifier,
|
|
21
|
+
store, fetch, Finish, or replay.
|
|
22
|
+
|
|
23
|
+
## Release boundary
|
|
24
|
+
|
|
25
|
+
Fresh Source and Package gates must bind the exact `0.8.22` candidate and its
|
|
26
|
+
canonical tar before protected integration, stable Release, and one npm
|
|
27
|
+
`latest` publication. A released successor package is the lawful fixture-pin
|
|
28
|
+
trigger for #307; fixture and V4 observations remain separately governed.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "persona-harness",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.22",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "npm@10.8.2",
|
|
@@ -248,6 +248,8 @@
|
|
|
248
248
|
"scripts/consumer-authority-v0820-acceptance-schema.mjs",
|
|
249
249
|
"scripts/consumer-authority-v0821-acceptance-schema.d.mts",
|
|
250
250
|
"scripts/consumer-authority-v0821-acceptance-schema.mjs",
|
|
251
|
+
"scripts/consumer-authority-v0822-acceptance-schema.d.mts",
|
|
252
|
+
"scripts/consumer-authority-v0822-acceptance-schema.mjs",
|
|
251
253
|
"scripts/consumer-authority-v081-acceptance-schema.d.mts",
|
|
252
254
|
"scripts/consumer-authority-v081-acceptance-schema.mjs",
|
|
253
255
|
"scripts/consumer-authority-rc1-acceptance-schema.mjs",
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export const V0822_ACCEPTANCE_SCHEMA_VERSION: "consumer-authority-v0822-acceptance.1"
|
|
2
|
+
|
|
3
|
+
export class V0822AcceptanceManifestError extends Error {
|
|
4
|
+
readonly code: "v0822-acceptance-schema"
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export type V0822AcceptanceManifest = Readonly<Record<string, unknown>> & Readonly<{
|
|
8
|
+
readonly authority: Readonly<{
|
|
9
|
+
readonly readOnlyVerify: Readonly<{
|
|
10
|
+
readonly archiveInput: Readonly<{
|
|
11
|
+
readonly ancestorDirectoryChurn: string
|
|
12
|
+
readonly arbitrarySymlinkAncestorOrLeaf: string
|
|
13
|
+
readonly darwinSystemTemporaryAlias: string
|
|
14
|
+
readonly directParentIntegrity: string
|
|
15
|
+
readonly nonDarwin: string
|
|
16
|
+
}>
|
|
17
|
+
readonly artifactDigestInput: string
|
|
18
|
+
readonly command: string
|
|
19
|
+
readonly noCredentialFetchStoreConsumeFinishReplay: boolean
|
|
20
|
+
readonly schemaVersion: string
|
|
21
|
+
}>
|
|
22
|
+
}>
|
|
23
|
+
readonly package: Readonly<{
|
|
24
|
+
readonly channel: string
|
|
25
|
+
readonly scope: string
|
|
26
|
+
readonly version: string
|
|
27
|
+
}>
|
|
28
|
+
readonly initialization: Readonly<{
|
|
29
|
+
readonly packageTemplateIdentity: string
|
|
30
|
+
readonly repairStaging: string
|
|
31
|
+
}>
|
|
32
|
+
readonly projectFinishSourceIdentity: Readonly<{
|
|
33
|
+
readonly adoptedInstructionPolicy: string
|
|
34
|
+
readonly repairInferenceObservations: string
|
|
35
|
+
}>
|
|
36
|
+
}>
|
|
37
|
+
|
|
38
|
+
export function canonicalV0822AcceptanceManifest(): V0822AcceptanceManifest
|
|
39
|
+
export function readV0822AcceptanceManifest(packageRoot: string): V0822AcceptanceManifest
|
|
40
|
+
export function parseV0822AcceptanceManifest(value: unknown, packageVersion: string): V0822AcceptanceManifest
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs"
|
|
2
|
+
import { join } from "node:path"
|
|
3
|
+
import { isDeepStrictEqual } from "node:util"
|
|
4
|
+
|
|
5
|
+
import { canonicalV0821AcceptanceManifest } from "./consumer-authority-v0821-acceptance-schema.mjs"
|
|
6
|
+
import { parseCanonicalPackagePublisherPlan } from "./canonical-package-publisher.mjs"
|
|
7
|
+
import { parseExternalArtifactTransportPlan } from "./consumer-authority-external-artifact-transport-plan.mjs"
|
|
8
|
+
import { parseExternalAttestationCommandPlan } from "./consumer-authority-external-attestation-command-plan.mjs"
|
|
9
|
+
import { parseObserverGhToolContract } from "./consumer-authority-observer-gh-tool.mjs"
|
|
10
|
+
|
|
11
|
+
export const V0822_ACCEPTANCE_SCHEMA_VERSION = "consumer-authority-v0822-acceptance.1"
|
|
12
|
+
|
|
13
|
+
const V0822_PACKAGE_VERSION = "0.8.22"
|
|
14
|
+
const ACCEPTANCE_PATH = join("docs", "current", "release", "consumer-authority-v0822-acceptance.json")
|
|
15
|
+
const EXPECTED_MANIFEST = buildExpectedManifest()
|
|
16
|
+
|
|
17
|
+
export class V0822AcceptanceManifestError extends Error {
|
|
18
|
+
constructor(code) {
|
|
19
|
+
super(code)
|
|
20
|
+
this.code = code
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function canonicalV0822AcceptanceManifest() {
|
|
25
|
+
return structuredClone(EXPECTED_MANIFEST)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function readV0822AcceptanceManifest(packageRoot) {
|
|
29
|
+
let packageVersion
|
|
30
|
+
let value
|
|
31
|
+
try {
|
|
32
|
+
packageVersion = JSON.parse(readFileSync(join(packageRoot, "package.json"), "utf8")).version
|
|
33
|
+
value = JSON.parse(readFileSync(join(packageRoot, ACCEPTANCE_PATH), "utf8"))
|
|
34
|
+
} catch {
|
|
35
|
+
fail()
|
|
36
|
+
}
|
|
37
|
+
return parseV0822AcceptanceManifest(value, packageVersion)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function parseV0822AcceptanceManifest(value, packageVersion) {
|
|
41
|
+
if (packageVersion !== V0822_PACKAGE_VERSION || !isDeepStrictEqual(value, EXPECTED_MANIFEST)) fail()
|
|
42
|
+
parseCanonicalPackagePublisherPlan(value.canonicalPackagePublisherPlan)
|
|
43
|
+
parseExternalAttestationCommandPlan(value.externalAttestationCommandPlan)
|
|
44
|
+
parseExternalArtifactTransportPlan(value.externalArtifactTransportPlan)
|
|
45
|
+
parseObserverGhToolContract(value.observerGhTool)
|
|
46
|
+
return value
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function buildExpectedManifest() {
|
|
50
|
+
const manifest = canonicalV0821AcceptanceManifest()
|
|
51
|
+
manifest.schemaVersion = V0822_ACCEPTANCE_SCHEMA_VERSION
|
|
52
|
+
manifest.package.channel = "unpublished"
|
|
53
|
+
manifest.package.scope = "source-candidate"
|
|
54
|
+
manifest.package.version = V0822_PACKAGE_VERSION
|
|
55
|
+
delete manifest.v0820HistoricalRelease
|
|
56
|
+
manifest.v0821HistoricalRelease = {
|
|
57
|
+
outcome: "published-0.8.21-release-is-immutable-and-not-reusable-for-this-unpublished-v0822-source-candidate-or-any-later-package",
|
|
58
|
+
reusableForV0822: false,
|
|
59
|
+
version: "0.8.21",
|
|
60
|
+
}
|
|
61
|
+
manifest.initialization = {
|
|
62
|
+
packageTemplateIdentity: "canonical-package-template-digest-remains-separate-from-effective-bootstrap-overlay-file-digests",
|
|
63
|
+
repairStaging: "manifest-less-recognized-portable-static-baseline-records-the-caller-realpath-before-staging-ownership-verification",
|
|
64
|
+
}
|
|
65
|
+
manifest.projectFinishSourceIdentity = {
|
|
66
|
+
adoptedInstructionPolicy: "remains-source-bound",
|
|
67
|
+
repairInferenceObservations: "excludes-only-.persona/instructions/inferred.json-and-.persona/instructions/conflicts.json",
|
|
68
|
+
}
|
|
69
|
+
manifest.authority.readOnlyVerify.archiveInput = {
|
|
70
|
+
...manifest.authority.readOnlyVerify.archiveInput,
|
|
71
|
+
ancestorDirectoryChurn: "same-no-follow-directory-location-and-mode-required-while-unrelated-entry-metadata-may-change",
|
|
72
|
+
directParentIntegrity: "full-no-follow-identity-remains-required-before-read",
|
|
73
|
+
}
|
|
74
|
+
manifest.authority.readOnlyVerify.artifactDigestInput = "canonical-sha256-prefix-or-exact-64-hex-normalized-before-archive-verification"
|
|
75
|
+
manifest.authority.fixturePlan.registryInstall = "requires-authorized-release-before-registry-install-persona-harness@0.8.22"
|
|
76
|
+
manifest.authority.hostedFixture.revision = "v0822-source-candidate-head-before-authorized-release"
|
|
77
|
+
manifest.hostedResidual.id = "v0822-current-package-acceptance-and-authorized-current-artifact-observation"
|
|
78
|
+
return manifest
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function fail() {
|
|
82
|
+
throw new V0822AcceptanceManifestError("v0822-acceptance-schema")
|
|
83
|
+
}
|
|
@@ -2,7 +2,7 @@ import { realpathSync } from "node:fs"
|
|
|
2
2
|
import { dirname } from "node:path"
|
|
3
3
|
import { fileURLToPath, pathToFileURL } from "node:url"
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { readV0822AcceptanceManifest } from "./consumer-authority-v0822-acceptance-schema.mjs"
|
|
6
6
|
import { runExternalArtifactTransportPreflight } from "./consumer-authority-external-artifact-transport-plan.mjs"
|
|
7
7
|
|
|
8
8
|
const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)))
|
|
@@ -14,7 +14,7 @@ async function main() {
|
|
|
14
14
|
process.exitCode = 1
|
|
15
15
|
return
|
|
16
16
|
}
|
|
17
|
-
|
|
17
|
+
readV0822AcceptanceManifest(packageRoot)
|
|
18
18
|
const result = await runExternalArtifactTransportPreflight()
|
|
19
19
|
process.stdout.write(`${JSON.stringify(result)}\n`)
|
|
20
20
|
process.exitCode = result.state === "ready" ? 0 : 1
|
|
@@ -2,7 +2,7 @@ import { realpathSync } from "node:fs"
|
|
|
2
2
|
import { dirname } from "node:path"
|
|
3
3
|
import { fileURLToPath, pathToFileURL } from "node:url"
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { readV0822AcceptanceManifest } from "./consumer-authority-v0822-acceptance-schema.mjs"
|
|
6
6
|
import { runExternalAttestationGrammarPreflight } from "./consumer-authority-external-attestation-command-plan.mjs"
|
|
7
7
|
|
|
8
8
|
const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)))
|
|
@@ -15,7 +15,7 @@ function main() {
|
|
|
15
15
|
process.exitCode = 1
|
|
16
16
|
return
|
|
17
17
|
}
|
|
18
|
-
const manifest =
|
|
18
|
+
const manifest = readV0822AcceptanceManifest(packageRoot)
|
|
19
19
|
const result = runExternalAttestationGrammarPreflight(
|
|
20
20
|
manifest.externalAttestationCommandPlan,
|
|
21
21
|
grammarOnlyTopology(manifest),
|