mirror of
https://github.com/morluto/rea.git
synced 2026-11-06 14:56:32 +00:00
* feat(harmony): disclose unclassified inventory files * test(harmony): let createEvidence own JSON admission in the partial-inventory case * test(harmony): extract the projection assertion from the archive journey * docs(harmony): qualify the unclassified disclosure rules and pin exact-case manifests * test(harmony): replace limitation prose with structured coverage facts The partial-inventory control froze the sentence "Source inventory coverage is partial; absence is unknown." verbatim. docs/testing.md asserts structured limit facts instead of freezing explanatory sentences and puts documentation wording in review, so the sentence is no longer substring-matched. `coverage.status` is a disjunction of independent causes in this projection: incomplete inventory scope, unavailable content, and an exceeded bridge budget. Asserting only `status: "partial"` left that attribution unstated, so the two other causes are now pinned as well. `unavailable_components` being empty and `bridge_candidate_coverage` being complete with zero candidates make the partial result attributable to the missing occurrence alone. Also drops an `artifact_id` comparison that could not fail: the fixture's four files carry the same bytes, the preceding assertion already pins that shared digest, and `artifact_id` is derived from the digest. Distinct paths sharing content stay covered by the path array and the independent digest expectations. Narrows a comment that claimed exact-case matching for every name in the control; only the manifest names are case-sensitive, because the App Pack child suffix match is case-insensitive. * docs(harmony): name the disclosure location for a nested child package The unclassified-disclosure paragraph used "there" to refer back to a clause that had just named `app_pack_children`, so a reader could take a nested `.hap` or `.hsp` member of a HAP or HSP root to be reported as an App Pack child. It is reported in `unclassified_components`: the child list is populated only for an App Pack root. Names the location explicitly.
119 lines
6.5 KiB
Markdown
119 lines
6.5 KiB
Markdown
# Static HarmonyOS package inventory
|
|
|
|
REA inventories HarmonyOS application packages through the shared hardened
|
|
ZIP artifact reader in `src/artifacts/`, then projects the authenticated
|
|
inventory into an execution-free application graph. This is the first
|
|
increment of the HarmonyOS roadmap (#1431): package identification and
|
|
component inventory only.
|
|
|
|
Recognized root formats:
|
|
|
|
- `.hap` — installable application module
|
|
- `.hsp` — runtime shared package
|
|
- `.app` — distribution App Pack (HAP/HSP children are listed by path). The
|
|
App Pack classification applies to verified-ZIP-magic root inputs only; a
|
|
nested ZIP member ending in `.app` inside another package, such as an IPA,
|
|
keeps the generic `zip` classification.
|
|
|
|
HarmonyOS `.har` shared libraries are intentionally not classified by suffix:
|
|
`.har` also names HTTP Archive JSON, so a Harmony shared archive requires
|
|
verified ZIP bytes and is deferred with an explicit limitation.
|
|
|
|
## Usage
|
|
|
|
No external SDK, toolchain, or engine is required. Inventory the package and
|
|
project the graph; CLI and MCP use the same workflow and return
|
|
artifact-bound Evidence inline:
|
|
|
|
```sh
|
|
rea inspect-artifact /path/to/Example.hap --format json > inspection.json
|
|
node --input-type=module -e 'import { readFileSync } from "node:fs"; console.log(JSON.stringify({ inventory_evidence: [JSON.parse(readFileSync("inspection.json", "utf8"))] }));' > projection-input.json
|
|
rea project-harmony-application-graph projection-input.json --format json
|
|
```
|
|
|
|
The MCP tool `project_harmony_application_graph` takes the same
|
|
`inventory_evidence` input. The projection reports:
|
|
|
|
- exact component paths, artifact IDs, and hashes (manifests, Ark bytecode,
|
|
resources, native libraries, JavaScript, signing)
|
|
- `unclassified_components` with the same paths and content identities for
|
|
authenticated files outside those categories and the App Pack child list
|
|
- a packaging-model hint: Stage is claimed only from an exactly cased `module.json` entry
|
|
outside a classified resource path, FA only from `config.json` outside a
|
|
classified resource path, otherwise `unknown`
|
|
- FA resources under `assets/<module>/resources/` as well as Stage `resources/`
|
|
- unavailable component paths with unknown IDs and hashes, including encrypted entries; these make projection coverage partial
|
|
- App Pack child package paths without recursive inventory
|
|
- runtime-family hints (`ark`, `native`, `javascript`) from paths and formats
|
|
- path-based N-API bridge hypotheses between bytecode and `libs/<abi>` native
|
|
libraries
|
|
|
|
An unavailable manifest can still supply a path-based model hint; its content
|
|
identity remains unknown. Manifest names follow case-sensitive ZIP member names.
|
|
|
|
File and slice occurrences supply component and child-package paths; directory
|
|
trees and symlinks retain their identities in the source inventory without
|
|
being classified as code files. Ark and JavaScript runtime hints summarize the
|
|
classified bytecode and JavaScript lists; supported source extensions share the
|
|
same classification rule as their component rows.
|
|
|
|
`unclassified_components` preserves files such as `pkgContextInfo.json`,
|
|
`.pages.info`, a HarmonyOS `.har` shared library, and a non-certificate
|
|
`META-INF` entry without interpreting their contents. The `.har` suffix also
|
|
names HTTP Archive JSON, so identifying one needs verified ZIP bytes rather than
|
|
a path rule. Different paths sharing the same bytes remain separate entries. App
|
|
Pack children of an App Pack root are already reported in `app_pack_children`,
|
|
so they are not repeated as unclassified files. A nested `.hap` or `.hsp` member
|
|
of a HAP or HSP root is disclosed in `unclassified_components` instead, because
|
|
child-package inventory is not recursive. Unreadable or encrypted content remains
|
|
in `unavailable_components` with unknown identity instead.
|
|
|
|
`coverage.status: "complete-within-inventory"` describes the authenticated
|
|
source inventory and bounded bridge projection, not semantic understanding of
|
|
every file. Unclassified files do not make a complete inventory partial; missing
|
|
inventory pages, source coverage limits, unavailable content and bridge limits
|
|
still qualify coverage independently. An empty unclassified list on a partial
|
|
inventory does not establish that the whole package has no unclassified files.
|
|
|
|
Every claim is path-presence only. Manifest semantics (module identity,
|
|
abilities, entry points, permissions, dependencies), Ark bytecode contents and
|
|
versions, resource resolution, signing verification, and observed native
|
|
boundaries are out of scope for this increment and stay in the projection's
|
|
`limitations` array until a dedicated HarmonyOS provider exists. REA fails
|
|
closed on packages whose inventory cannot be authenticated.
|
|
|
|
## Verification lane
|
|
|
|
`npm run fixtures:harmony` downloads the SHA-256-pinned 1.0.1 HAP release
|
|
from the MIT-licensed [harmony-next-pipeline source repository](https://github.com/ohosvscode/harmony-next-pipeline)
|
|
into ignored `_reference/harmony-integration/`. The pin records the source
|
|
revision, release asset ID, size, and digest. The downloaded artifact is not
|
|
redistributed; bundled component licenses have not been independently audited.
|
|
|
|
```sh
|
|
npm run fixtures:harmony
|
|
REA_HARMONY_TEST_HAP=_reference/harmony-integration/entry-default-unsigned.hap \
|
|
npm run verify:harmony
|
|
```
|
|
|
|
The lane exercises the compiled CLI and actual SDK-connected stdio MCP:
|
|
`inspect_artifact` authenticity, projection determinism, Stage-model path hints,
|
|
exact manifest/bytecode/resource component sets, empty native and bridge sets,
|
|
complete-inventory coverage, and CLI/MCP parity. It checks that this fixture has
|
|
no META-INF signing entries; that does not establish whether the package is signed.
|
|
|
|
The release artifact's compiler/SDK versions and reproducible source build have
|
|
not been independently established. This lane does not complete the pinned
|
|
toolchain acceptance in #1431 and does not verify Ark decoding or signatures.
|
|
Set `REA_HARMONY_ENTRYPOINT` to an installed package's `scripts/rea.mjs` to run
|
|
the same checks against that package; the default lane uses the repository build.
|
|
|
|
Packaging-model and App Pack child presence use inventoried file/slice paths even
|
|
when encrypted content cannot be authenticated. Unavailable App Pack children
|
|
retain their path, format, encryption and limitations with null artifact ID and
|
|
digest; they do not establish decoded package semantics. Missing source nodes
|
|
outside supplied pages retain the inventory limitation and partial coverage.
|
|
The signing list includes inventoried META-INF RSA, DSA and EC certificate-block
|
|
paths alongside the existing suffixes; opaque content does not establish a valid
|
|
signature or certificate.
|