Skip to content

M2-10: Assemble DecisionInput, PreflightReport and presentation model #31

Closed

Description

@pillowtalk-Qy
Type: Core Assembly Implementation
Priority: P0 / trust boundary
Initial status: Blocked
Owner: Contract/Security
Depends on: M1-08, #6, M2-09
Blocks: M2-12
Writable: preflight-core assemble*, presentation*, index*, tests

唯一目标

组装合法 DecisionInput,调用唯一 Decision Engine,再组装合法 PreflightReport v0.1 和独立 display/presentation model。

验收

[ ] DecisionInput 在 evaluate 前 parse
[ ] 只调用 decision-engine public API
[ ] final report 经 PreflightReportSchema parse
[ ] generatedAt/network/provenance/limitations 完整
[ ] block/Moss info 位于 /simulation/raw/context
[ ] 不增加未批准 top-level field
[ ] presentation 是 derived,不是 evidence
[ ] presentation 无法覆盖 raw code/message/value
[ ] STOP explanation 链接 raw refs
[ ] exact MANUAL_REVIEW 语义
[ ] 无 Clear402 import/dependency
[ ] deterministic inputs 除注入 metadata 外结构相等

验证

pnpm vitest run packages/preflight-core/test/assembler.test.ts
pnpm vitest run packages/preflight-core/test/presentation.test.ts
pnpm --filter @moss-mini-demo/preflight-core build
pnpm check

Codex 指令

通过 public schemas/API 组装,不在 assembler 复制 Decision 规则。
严格保持 PreflightReport v0.1 top-level;展示模型只能引用/解释 raw evidence。

Activity

  1. 1 remaining item

  2. pillowtalk-Qy commented on Aug 8, 2026

    @pillowtalk-Qy
    ContributorAuthor

    Dependency gate cleared -> Ready

    Validated all direct dependencies against protected main 88cc27b5464fa8725e31f0ea450620f70fe48c40:

    No open implementation PR or assigned code WIP exists. Removed status:blocked, added status:ready, and moved the Project item from Blocked to Ready. No branch/worktree has been created.

  3. self-assigned this
    on Aug 8, 2026
  4. pillowtalk-Qy commented on Aug 8, 2026

    @pillowtalk-Qy
    ContributorAuthor

    Builder claim - M2-10

    Claimed by pillowtalk-Qy under the single-operator protocol after the dependency gate cleared.

    • Project: Ready -> In Progress
    • Removed transient status:ready; no status label while active
    • Repository code WIP: M2-10: Assemble DecisionInput, PreflightReport and presentation model #31 only
    • Open implementation PRs: none
    • Planning baseline: protected main 88cc27b5464fa8725e31f0ea450620f70fe48c40
    • Writable scope remains limited to preflight-core assembler/presentation/public-entry/tests plus only the root package/lock changes explicitly justified by the forthcoming reviewed Work Plan

    No implementation branch/worktree will be created until the Work Plan is published and self-reviewed.

  5. pillowtalk-Qy commented on Aug 8, 2026

    @pillowtalk-Qy
    ContributorAuthor

    Work Plan - M2-10 report assembly and presentation sidecar

    Baseline and dependency gate

    Resolved assembly contract

    The implementation will follow the Issue body, public PreflightReport/DecisionInput schemas, ADRs 0001/0003/0004, docs/stop-presentation.md, the engineering plan/backlog, and the already merged #30 package boundary.

    1. Public assembly is assemblePreflightReportV0_1(source, metadata). source is a strict v0.1 object containing only schemaVersion, intent, quotes, selection, capability, simulation, and the M2-09: Implement deterministic preflight alignment #30-produced alignment. metadata is a separate strict injected object containing only reportId, generatedAt, network, provenance, and limitations.
    2. The assembler constructs the exact public DecisionInputV0_1 projection from those two parsed inputs and parses it with DecisionInputV0_1Schema before evaluation. It then calls only the public evaluateDecisionV0_1 export from @moss-mini-demo/decision-engine and never imports package internals or duplicates any Decision trigger, rank, aggregation, or MANUAL_REVIEW rule.
    3. The assembler adds only the returned Decision and parsed limitations, then parses the complete result through PreflightReportSchema. No new PreflightReport top-level field, extension, display value, or convenience alias is permitted.
    4. generatedAt is caller-injected canonical metadata. Assembly reads no clock, environment, randomness, network, filesystem, or Moss/Clear402 runtime. Repeated equal source/metadata values produce structurally equal fresh reports and do not mutate or freeze caller inputs.
    5. When simulation is AVAILABLE, its already source-owned raw artifact must contain non-empty object records at /simulation/raw/context/block and /simulation/raw/context/moss. The assembler preserves these raw values; it does not move block/Moss identity to report top level, infer a block/hash, or import moss-adapter. An unavailable simulation remains a valid fail-closed DecisionInput path and is not forced to invent raw context.

    Hostile-input boundary

    Both public functions accept unknown. Before Zod or Decision Engine property traversal, assembler-owned descriptor-safe JSON cloning will reject accessors, Proxy objects, symbols, functions, cycles, sparse/malformed arrays, custom prototypes, prototype-related own keys, non-finite numbers, negative zero, and lone surrogates. Acyclic repeated object references are accepted and cloned independently because #28 raw Moss evidence may intentionally share Change/Receipt object identity even though the report contract is JSON-shaped.

    PreflightAssemblyErrorV0_1 will expose stable codes for unsupported source version, invalid source, invalid metadata, missing required available-simulation context, and an impossible invalid final report. A public Decision Engine validation error remains Decision Engine-owned; the assembler will not reinterpret it as a STOP or catch a programming invariant and manufacture evidence.

    Independent presentation sidecar

    Public derivePreflightPresentationV0_1(report) first descriptor-safely clones and validates the complete report with PreflightReportSchema. It returns a fresh PreflightPresentationV0_1 sidecar, never a report extension:

    • MANUAL_REVIEW preserves the exact nested Decision shape { status: "MANUAL_REVIEW" }, with no reasons property and no approval/safety/signing claim.
    • STOP contains stable heading/action-boundary fields plus one derived entry for every Engine reason in unchanged order. Each entry preserves the exact StopReasonCodeV0_1 and exact Engine-provided SourceReferences and adds only a fixed bounded explanation keyed by that code.
    • The sidecar references source context only through /simulation/raw/context/block and /simulation/raw/context/moss, when those source-owned values exist, and references limitations only through deterministic /limitations/<index> pointers.
    • It never accepts caller-provided presentation overrides and never copies or reconstructs source-owned raw code, message, value, transaction, block, or Moss fields. A consumer resolves the preserved report-local reference against the validated report, so presentation mutation cannot alter evidence or Decision.
    • Every independent STOP reason remains present; there is no first-reason collapse, reason reassignment, generated pointer, signing bypass, or presentation-as-evidence path.

    Public API

    Extend only @moss-mini-demo/preflight-core public entry with:

    • runtime: assemblePreflightReportV0_1, derivePreflightPresentationV0_1, and PreflightAssemblyErrorV0_1, alongside the existing alignment runtime exports;
    • type-only: PreflightAssemblySourceV0_1, PreflightAssemblyMetadataV0_1, PreflightPresentationV0_1, and its closed decision/reason/context support types;
    • one new workspace dependency on @moss-mini-demo/decision-engine; no Clear402, moss-adapter, server-only, network, UI, or external package dependency.

    Exact writable paths

    Implementation is authorized only in these eight paths:

    1. pnpm-lock.yaml
    2. packages/preflight-core/package.json
    3. packages/preflight-core/src/assembler.ts
    4. packages/preflight-core/src/presentation.ts
    5. packages/preflight-core/src/index.ts
    6. packages/preflight-core/test/assembler.test.ts
    7. packages/preflight-core/test/presentation.test.ts
    8. packages/preflight-core/test/public-entry.smoke.mjs

    The package manifest change adds the workspace Decision Engine dependency and includes the two new focused suites in the existing 100% v8 coverage command. The lockfile delta is limited to that workspace link. Existing test/synthetic.ts is consumed unchanged by local test builders. Any need for another path, external dependency, report-schema/Decision Engine rule change, adapter import, root script, Web, workflow, vendor, ADR, or governance edit stops implementation for a prior scope amendment.

    Assembly test matrix

    assembler.test.ts will cover:

    • valid M2-09: Implement deterministic preflight alignment #30 Alignment -> parsed DecisionInput -> exact MANUAL_REVIEW -> final PreflightReport parse;
    • STOP assembly with the public Engine's complete canonical reason set and exact raw-backed references;
    • source and metadata strict unknown-key rejection, unsupported versions, malformed public components, final top-level closure, and no display fields in the report;
    • complete injected reportId/generatedAt/network/provenance/limitations retention;
    • required available-simulation raw.context.block and .moss location, non-empty-object checks, top-level block/Moss rejection, and unavailable-simulation fail-closed assembly without invented raw context;
    • public Engine ownership of no-critical-alignment rejection and absence of copied Decision rules in assembler;
    • caller graph immutability/unfrozen state, fresh outputs, repeated deterministic equality, metadata-only variation, and source projection equality;
    • no clock/random/fetch/environment/Moss/Clear402 access;
    • descriptor-hostile inputs, cycles, malformed JSON values, and allowed acyclic shared raw identity.

    Presentation test matrix

    presentation.test.ts will cover:

    • exact MANUAL_REVIEW semantics with no reasons or approval implication;
    • STOP heading, signer boundary, every reason in Engine order, one bounded explanation per reason, and byte-equal reason-specific SourceReferences;
    • raw Warning code/message/value, block context, and Moss context remain only in the report and are unchanged; no presentation input can override them;
    • context and limitation references resolve to their exact report-local values, remain context rather than reason evidence, and are omitted where the source does not exist;
    • invalid/unparsed reports and unknown top-level fields are rejected;
    • report immutability, fresh/deterministic sidecars, mutation isolation, hostile descriptors/Proxy/cycles, and no I/O/time/randomness;
    • public-entry smoke proves the exact runtime/type-only export boundary and import-time side-effect absence.

    Verification and lifecycle

    Implementation worktree and later detached clean QA will run, at the exact frozen HEAD:

    1. pnpm install --frozen-lockfile
    2. build public dependencies, then pnpm vitest run packages/preflight-core/test/assembler.test.ts
    3. pnpm vitest run packages/preflight-core/test/presentation.test.ts
    4. pnpm --filter @moss-mini-demo/preflight-core build
    5. pnpm test:coverage with 100% statements/branches/functions/lines
    6. pnpm test:package-import
    7. full no-dist pnpm check
    8. pnpm audit --prod, secret/Clear402/dependency/path/generated-artifact scans, git diff --check, and worktree cleanliness
    9. exact-head PR quality-gate, SINGLE_OPERATOR_QA_PASS from a separate clean detached worktree, READY_TO_MERGE, protected squash merge, merged-main quality-gate, accepted/merged tree equivalence, protection audit, Issue/Project closure, and branch/worktree cleanup.

    Explicit non-goals and stop conditions

    • No quote/action/simulation mapping, M2-09: Implement deterministic preflight alignment #30 Alignment calculation, orchestrator/API, live smoke, UI, signer, wallet, transaction submission, or Clear402 integration.
    • No claim that MANUAL_REVIEW means safe, approved, executable, or authorized.
    • No presentation prose may create evidence, repair a pointer, suppress a reason, or override raw source values.
    • Stop before editing outside the eight paths or if the existing public schemas/Decision Engine cannot satisfy the acceptance criteria without a contract amendment.

    WORK_PLAN_V1_SUBMITTED / AWAITING_SINGLE_OPERATOR_SCOPE_REVIEW

  6. pillowtalk-Qy commented on Aug 8, 2026

    @pillowtalk-Qy
    ContributorAuthor

    SINGLE_OPERATOR_SCOPE_REVIEW / Work Plan self-review - PASS

    This is a same-controller review by Qy, not an independent reviewer claim.

    Reviewed immutable planning object:

    Scope and contract findings:

    • Dependency/order: PASS. M1-08/M1-08: Implement ADR 0004 DecisionInput and STOP reason boundary #19, M1-03: Implement fail-closed decision engine #6, and M2-09: Implement deterministic preflight alignment #30 are merged/closed/Done with recorded tree and merged-main gate evidence. M2-10: Assemble DecisionInput, PreflightReport and presentation model #31 is next in the frozen batch order, is the sole assigned code WIP, and has no competing PR.
    • Assembly ownership: PASS. The source/metadata split is strict and sufficient to construct the public DecisionInput without adding report fields. Alignment is consumed from M2-09: Implement deterministic preflight alignment #30; M2-10: Assemble DecisionInput, PreflightReport and presentation model #31 does not recalculate or caller-invent Decision rules.
    • Decision boundary: PASS. DecisionInputV0_1Schema parse precedes the sole public evaluateDecisionV0_1 call. Trigger/rank/aggregation/MANUAL_REVIEW logic remains exclusively in decision-engine. Engine validation errors are not caught and relabeled as domain STOP.
    • Final schema: PASS. The exact report projection adds only Decision and limitations and is reparsed with PreflightReportSchema; unapproved top-level/display extensions cannot pass.
    • Metadata/context: PASS. All required injected report metadata is explicit. Available simulation requires non-empty block and Moss records only under /simulation/raw/context; unavailable simulation is allowed to remain explicit failed/missing/unprovable evidence rather than fabricating context.
    • Presentation separation: PASS. The sidecar is derived only from a validated final report, accepts no override object, preserves exact reason order/code/references, links context/limitations by report-local pointers, and never copies/reconstructs raw code/message/value. MANUAL_REVIEW remains exactly reasonless and carries no approval/signing implication.
    • SourceReference semantics: PASS. The plan preserves the Engine references exactly, including explicit selection/availability fields where the public v0.1 Decision contract intentionally uses them. It does not falsify those fields as raw paths merely to satisfy display wording.
    • Hostile/raw graph compatibility: PASS. Descriptor-safe cloning happens before parser traversal and rejects active hazards while accepting acyclic shared raw identities established by M2-07: Implement simulation and lossless evidence mapping #28, then normalizes them into independent JSON-shaped data.
    • Determinism: PASS. Time and identity values are injected; equality, freshness, no mutation, metadata-only variation, and no I/O/time/randomness are all testable.
    • Dependencies: PASS. The only dependency delta is the existing workspace Decision Engine. No external package, Clear402, moss-adapter, server-only, or UI dependency is added; lock change is one workspace importer link.
    • Tests/coverage: PASS. Focused assembly/presentation, hostile boundary, exact MANUAL_REVIEW/STOP, context, presentation isolation, public entry, 100% package coverage, full repository check, clean QA, audit, and CI gates cover every Issue acceptance item.
    • Closed scope: PASS. The exact eight paths are sufficient. Existing synthetic input can be adapted in the new test files without editing shared fixtures. No root script, Schema, Engine implementation, adapter, Web, workflow, vendor, docs, or governance path is hidden.
    • Merge lifecycle: PASS. Frozen head, separate clean SINGLE_OPERATOR_QA, exact-head CI, protected squash merge, merged-main CI, tree equivalence, protection audit, closure, and cleanup are explicit.

    No scope finding remains open and no scope amendment is required. The published hash is accepted as the implementation contract.

    Authorized next state:

    • branch: codex/issue-31-report-assembly
    • isolated implementation worktree: /Users/qy/Documents/moss-mini-demo-issue-31
    • exact baseline: 88cc27b5464fa8725e31f0ea450620f70fe48c40

    Any baseline, path, dependency, API, report top-level, Decision ownership, or evidence/presentation-boundary change invalidates this authorization until a prior reviewed scope amendment.

    SINGLE_OPERATOR_SCOPE_REVIEW_PASS / SCOPE_CONFIRMED / IMPLEMENTATION_AUTHORIZED

  7. pillowtalk-Qy commented on Aug 8, 2026

    @pillowtalk-Qy
    ContributorAuthor

    SCOPE_AMENDMENT_1 / REQUESTED

    The first exact-head clean CI run exposed one dependency-order path missing from Work Plan v1.

    Evidence:

    Cause: root typecheck currently builds report-schema and then preflight-core. #31 adds preflight-core's public workspace dependency on decision-engine, so clean dependency order must be report-schema -> decision-engine -> preflight-core. The local implementation gate had pre-existing decision-engine dist from the preceding public-entry smoke and therefore did not expose this ordering defect.

    Requested ninth writable path:
    9. package.json

    The only authorized edit is to insert:
    pnpm --filter @moss-mini-demo/decision-engine build
    between the existing report-schema and preflight-core builds in the root typecheck script.

    No other root script, dependency, source, test, workflow, package, lockfile, API, report shape, Decision rule, presentation behavior, or path changes. Root build and test:package-import already use the correct order and remain unchanged.

    The prior frozen head and its CI result are invalidated for QA/merge. After authorization, implementation returns to IMPLEMENT, creates a new commit/head, reruns focused/coverage/full local gates, and requires a new exact-head CI before QA handoff.

    SCOPE_AMENDMENT_1_SUBMITTED / AWAITING_SINGLE_OPERATOR_SCOPE_REVIEW

  8. pillowtalk-Qy commented on Aug 8, 2026

    @pillowtalk-Qy
    ContributorAuthor

    SINGLE_OPERATOR_SCOPE_REVIEW / AMENDMENT_1 / PASS

    This is a same-controller scope review by Qy, not an independent reviewer claim.

    Reviewed amendment: #31 (comment)

    • exact body SHA-256, no added newline: 783a3d483259d69b87cb26bd15e27d64ed6ca91e7b033da8188574349d815979
    • exact CI reproduction: run 31240321651 / job 93060082512 at 8036c8202e0af72b3dec63c453ce64f089c32692

    Findings:

    • PASS: the failure is a clean-check dependency-order defect, not a source contract or test assertion bypass.
    • PASS: decision-engine is the declared new direct public dependency of preflight-core.
    • PASS: report-schema -> decision-engine -> preflight-core is the real build graph and matches the existing root build and test:package-import order.
    • PASS: package.json is the only additional path required.
    • PASS: the exact edit is one command insertion in root typecheck; no other script or dependency changes.
    • PASS: putting transitive workspace builds inside preflight-core's package-local build script would duplicate centralized ordering and diverge from repository conventions, so the root order correction is the narrower correct fix.
    • PASS: all original source, API, report, Decision, presentation, hostile-input, dependency, lock, test, non-goal, and lifecycle constraints remain unchanged.
    • PASS: prior head/CI is explicitly invalidated; new local gates and exact-head CI are mandatory.

    No amendment finding remains open.

    Qy authorizes the reviewed amendment as sole controller. The closed writable set is now the original eight paths plus exactly:
    9. package.json

    Within package.json, only the root typecheck dependency-order insertion described above is authorized. Any other edit requires another prior amendment.

    SINGLE_OPERATOR_SCOPE_REVIEW_PASS / SCOPE_AMENDMENT_1_AUTHORIZED / RETURN_TO_IMPLEMENT

  9. pillowtalk-Qy commented on Aug 8, 2026

    @pillowtalk-Qy
    ContributorAuthor

    IMPLEMENTATION_FROZEN

    Draft PR #77 is frozen at accepted head 84fb2438da38232552e365d3a895e69df0ed2cb1, tree 2efeb5d047f6504bbf68f9a953baafbf1cb4b0e4.

    • exact-head quality-gate: success, run 31240497479 / job 93060536660
    • Implementation Report: M2-10: assemble reports and presentation sidecar #77 (comment)
    • reviewed scope including Amendment 1: exactly 9 paths, 1,453 additions / 2 deletions
    • local clean/no-dist pnpm check: passed, 31 files / 1,089 tests
    • preflight-core coverage: 100% statements/branches/functions/lines, 200 tests
    • worktree clean; local, remote, and PR head identical

    The initial failing head/run is retained transparently in the report and is not accepted. The current head now leaves IMPLEMENT and enters clean same-operator QA. No independent reviewer is claimed.

    IMPLEMENTATION_FROZEN / CLEAN_SINGLE_OPERATOR_QA_PENDING

  10. pillowtalk-Qy commented on Aug 8, 2026

    @pillowtalk-Qy
    ContributorAuthor

    SINGLE_OPERATOR_QA_HANDOFF

    This is same-operator QA, not an independent reviewer claim.

    QA will start from no dependencies/build artifacts, repeat the complete focused/coverage/full-gate and trust-boundary matrix, inspect the exact amended 9-path diff, and audit PR/protection state. Any head movement invalidates this handoff.

    SINGLE_OPERATOR_QA_HANDOFF / CLEAN_QA_START

  11. pillowtalk-Qy commented on Aug 8, 2026

    @pillowtalk-Qy
    ContributorAuthor

    SINGLE_OPERATOR_QA_PASS

    This is same-operator QA from a separate clean detached worktree; no independent reviewer is claimed.

    Accepted/frozen head 84fb2438da38232552e365d3a895e69df0ed2cb1 passed:

    • exact-head CI run 31240497479 / job 93060536660
    • frozen install on Node 22.23.1 / pnpm 11.16.0
    • assembler 24 tests and presentation 9 tests
    • preflight-core 200-test coverage at 100% statements/branches/functions/lines
    • public import boundary
    • a second explicit no-dist root pnpm check: 31 files / 1,089 tests plus all build/browser/production gates
    • exact 9-path Scope Amendment audit, hostile/presentation/raw-context boundaries, unchanged audit baseline, secret/Clear402/vendor scan, clean worktree, and PR/protection checks

    PR #77 is mergeable/CLEAN with 0 review threads and no head movement. Full QA record: #77 (comment)

    PASS. Any head movement invalidates this result.

    SINGLE_OPERATOR_QA_PASS / READY_FOR_MERGE_GATE_ASSESSMENT

  12. pillowtalk-Qy commented on Aug 8, 2026

    @pillowtalk-Qy
    ContributorAuthor

    READY_TO_MERGE

    PR #77 is ready at accepted head 84fb2438da38232552e365d3a895e69df0ed2cb1.

    Work Plan + Amendment, frozen Implementation Report, clean same-operator QA PASS, exact-head quality-gate run 31240497479/job 93060536660, 0 unresolved threads, mergeable/CLEAN state, exact 9-path scope, and protected squash-only policy have all been rechecked without head movement.

    Authorized next state: Ready, then protected squash merge. No independent reviewer or pre-merge completion claim.

    READY_TO_MERGE / PROTECTED_SQUASH_ONLY

  13. pillowtalk-Qy commented on Aug 8, 2026

    @pillowtalk-Qy
    ContributorAuthor

    READY_TO_MERGE

    PR #77 is ready at immutable head 84fb2438da38232552e365d3a895e69df0ed2cb1.

    Work Plan/Amendment, Implementation Report, separate clean SINGLE_OPERATOR_QA_PASS, exact-head quality-gate run 31240497479/job 93060536660, 0 unresolved threads, mergeable/CLEAN status, exact 9-path scope, and protected-main/squash-only policy have all been rechecked with no head movement.

    Authorized next state: leave Draft and use protected squash merge only.

    READY_TO_MERGE / PROTECTED_SQUASH_ONLY

  14. pillowtalk-Qy commented on Aug 8, 2026

    @pillowtalk-Qy
    ContributorAuthor

    POST_MERGE_AUDIT - PASS

    • PR M2-10: assemble reports and presentation sidecar #77 protected squash merge: 42637ff3e152e44de3c88848e30f1d2c666d0863
    • accepted head: 84fb2438da38232552e365d3a895e69df0ed2cb1
    • parent: baseline 88cc27b5464fa8725e31f0ea450620f70fe48c40; single-parent linear history verified
    • accepted/merged tree equality: 2efeb5d047f6504bbf68f9a953baafbf1cb4b0e4
    • merged-main quality-gate: run 31241419119 / job 93062942322, success
    • local/remote main synchronized; remote branch deleted
    • exact 9-path reviewed scope retained; protection and squash-only policy unchanged
    • PR audit record: M2-10: assemble reports and presentation sidecar #77 (comment)

    All implementation, clean QA, merge, and post-merge gates have passed. Move Project to Done and clean local environments.

    POST_MERGE_AUDIT_PASS / ISSUE_COMPLETE

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:architectureArchitecture and module boundariesarea:qaQuality assurance and testingpriority:P0Critical priorityrisk:trust-boundaryChanges a trust or evidence boundarytype:featureNew product functionality

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions