Manifest contract
package_manifest.json is the package-level contract that binds identity, artifacts,
checksums, profile semantics, capabilities, rights, counts, and validation state.
The manifest version is 1.2, delivery schema is 1.2, and source schema is 1.0. The
supported package revision is 1. The loader rejects any other manifest version with
manifest_version_unsupported.
Top-level fields
| Field | Purpose |
|---|---|
manifestVersion |
Manifest schema version |
frameworkId |
Framework-family identity |
snapshotId |
Immutable snapshot identity, namespaced by frameworkId |
graphPackageId |
Immutable package identity |
graphType |
Primary graph domain |
includedGraphTypes |
Graph domains included in the package |
packageRevision |
Package-format revision, currently 1 |
deliverySchemaVersion |
Delivery JSONL schema version. The supported version is 1.2 |
sourceSchemaVersion |
Detailed-source schema version |
createdAt |
Timezone-aware package creation timestamp |
framework |
Source-faithful and normalized framework metadata |
profile |
Exact interpretation-profile ID, version, and SHA-256 |
artifacts |
Logical artifact names mapped to package-relative paths |
checksums |
SHA-256 for every and only declared artifact path |
counts |
Declared graph and additional counts |
capabilities |
Snapshot/package search and provenance capabilities |
rights |
Accepted package rights/exposure metadata |
validation |
Package validation status and terminal timestamp |
snapshotRelations |
Optional operator-supplied relations to other immutable snapshots |
All public/config schemas serialize with lower-camel-case aliases even though the Python models use snake_case internally.
Identity rules
A valid manifest must satisfy several identity invariants:
snapshotIdbegins with the exactframeworkIdnamespace.graphTypeappears inincludedGraphTypes.includedGraphTypescontains no duplicates.- For an initial package whose
graphPackageIdequals thesnapshotId,packageRevisionmust be1and only the primarygraphTypemay be included. - Otherwise
graphPackageIdmust equal the deterministic graph-type/package-revision form accepted by the identifier contract. - A snapshot relation may not target the same snapshot or duplicate the same
(relationType, targetSnapshotId)pair.
The current packages including learning components and progressions declare
includedGraphTypes: [academic_standards, learning_components, learning_progressions]. Because an initial
graphPackageId may declare only its primary graph type, such a package uses the
deterministic graph-type/package-revision form instead, and its graphPackageId is
therefore longer than its snapshotId. Adding LP artifacts changes the artifact-set snapshot hash and package directory;
it does not create a new curriculum edition or change standard/component identifiers.
Framework metadata
The framework object records source-facing and normalized metadata such as:
name;jurisdictionand optionaljurisdictionType;issuingAuthorityandprovider;languages;localSubjectandnormalizedSubjects;localGradesOrStagesandnormalizedGrades;adoptionStatus;isCurrent;sourceVersion, optional publication date, and optional source-document SHA-256; and- subject-mapping status/note.
Normalized subject and grade metadata supports discovery. It does not overwrite local curriculum terminology or establish equivalence.
Profile reference
The profile binding is deliberately small and exact:
{
"profile": {
"profileId": "ghana-nacca-primary-english-language-basic-1-3",
"profileVersion": "2.0",
"sha256": "sha256:fe2b269f7e76d0abf89d00799857602e17c8e76b6d1b4055797c662629ce7212"
}
}
The loader computes SHA-256 over the exact resolved profile.json bytes and rejects a
mismatch.
Artifact declarations
The artifacts object always requires:
| Logical name | Role |
|---|---|
nodes |
Delivery node JSONL |
relationships |
Delivery relationship JSONL |
It can also declare these built-in artifacts:
| Logical name | Package path in the current packages | Content |
|---|---|---|
entityProvenance |
slim/as_entity_provenance.json |
Slim standards provenance |
standardsFramework |
detailed/as_standards_framework.json |
Framework JSON |
unresolvedItems |
detailed/as_unresolved_items.json |
Unresolved-evidence report JSON |
validationReport |
detailed/as_lc_validation_report.json |
Validation report JSON |
learningComponentSummary |
detailed/lc_generation_summary.json |
Learning-component generation summary JSON |
learningComponentProvenance |
slim/lc_entity_provenance.json |
Slim learning-component provenance |
learningComponentDedupGroups |
detailed/lc_dedup_groups.json |
Learning-component dedup groups JSON |
A package that includes learning progressions must declare these five LP artifacts:
| Logical name | Package path |
|---|---|
learningProgressionNormalization |
detailed/lp_normalization_receipt.json |
learningProgressionProvenanceIndex |
slim/lp_relationship_provenance_index.json |
learningProgressionSummary |
detailed/lp_generation_summary.json |
learningProgressionUnresolved |
detailed/lp_unresolved_items.json |
learningProgressionValidation |
detailed/lp_validation_report.json |
It must also declare the 64 slim shards as additional artifacts,
learningProgressionProvenanceShard00 to learningProgressionProvenanceShard63, at
slim/lp_relationship_provenance_shard_NN.json.
Every manifest must declare evidenceArchiveRecord as an additional artifact at
evidence/evidence_archive_record.json. See
Runtime files and archived evidence.
A manifest cannot declare archive-only evidence. These names are reserved and rejected,
both as built-in fields and as additional artifacts, even with a null value:
academicStandardsBundle
learningComponentsBundle
relationshipsHasChild
standardsFrameworkItems
learningProgressionFinalClaims
learningProgressionProvenance
learningProgressionBuildsTowards
learningProgressionRelatesTo
Their files are bound by hash in the evidence archive record instead.
additionalArtifacts can represent other logical artifacts, but names reserved by the
built-in fields are forbidden. Every declared artifact path must be unique.
A manifest declaration does not automatically make an artifact readable over MCP. See Rights and provenance and Resources reference.
Checksum closure
checksums must cover exactly the declared artifact paths:
A missing checksum or checksum for an undeclared path invalidates the manifest. During loading, each declared file is read and checked against its expected SHA-256 and size observation.
Counts
The version-1 count contract contains:
{
"counts": {
"frameworkNodes": 1,
"itemNodes": 430,
"learningComponentNodes": 0,
"relationships": 430,
"supportsRelationships": 0,
"buildsTowardsRelationships": 0,
"relatesToRelationships": 0,
"additionalCounts": {
"codedItems": 319,
"multiParentTargets": 0,
"unresolvedRelationships": 2
}
}
}
itemNodes counts standards framework items only and learningComponentNodes counts
generated learning components; the two are never combined. relationships counts every
relationship in the package, of which supportsRelationships are learning-component
edges. buildsTowardsRelationships and relatesToRelationships separately count LP
edges. Those four component/LP counts default to zero for packages without the declared
domains; all packages must still use current supported schemas. Counts are checked
against decoded content. Hierarchy/unresolved counts retain their original meaning.
frameworkNodes is exactly 1. Version 1 requires additionalCounts to contain
exactly these three names:
codedItems;multiParentTargets; andunresolvedRelationships.
The validator independently derives graph facts and compares them with the manifest and detailed validation report.
Capabilities
The capabilities object declares package-level behavior:
| Field | Meaning |
|---|---|
textSearch |
Lexical text search is supported |
codeSearch |
Code availability: complete, partial, or none |
multiParent |
Accepted hierarchy can contain multi-parent targets |
hasDetailedProvenance |
entityProvenance (slim standards provenance) is declared |
hasUnresolvedRelationships |
Package retains unresolved relationship evidence |
hasOfficialActivities |
Official activity-role nodes are represented |
hasOfficialAssessmentGuidance |
Official assessment-guidance role nodes are represented |
hasLearningProgressions and hasLearningProgressionProvenance must both equal
whether learning_progressions is in includedGraphTypes. When it is, the five LP
artifacts and 64 slim shards above must all be declared. A valid zero-edge LP package
also sets both flags. They do not follow from a global enum or a nonzero count alone.
Capabilities must agree with independently observed graph/profile facts. They are not free-form feature flags.
Rights
The manifest retains the accepted package rights object independently of artifact
presence. It includes source license/attribution plus operator exposure decisions such
as allowFullText, allowStandardResources, and allowBulkResource.
Validation state
validation is:
Supported states are pending, passed, failed, and quarantined.
A terminal state requires a timezone-aware validatedAt. A pending state must not
have one. The controlled validation transition changes only the validation object; it
must not alter package-defining manifest fields or createdAt.
Snapshot relations
snapshotRelations can record operator-supplied relations using:
Each relation identifies a target snapshot and can include evidence. The supplied seven packages currently declare no snapshot relations.
Next: Validation and lifecycle