qfai 2.1.0 → 2.1.2
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/README.md +327 -55
- package/assets/defaults/agent-routing/qfai-triage.yml +9 -0
- package/assets/defaults/workflows/change-tooling.yml +0 -4
- package/assets/defaults/workflows/run-owned-cleanup.yml +12 -0
- package/assets/init/.claude/settings.json +27 -9
- package/assets/init/.codex/hooks.json +20 -8
- package/assets/init/.qfai/assistant/agent/frontend-engineer.md +5 -0
- package/assets/init/.qfai/assistant/agent/implementation-reviewer.md +14 -1
- package/assets/init/.qfai/assistant/agent/product-experience-architect.md +4 -0
- package/assets/init/.qfai/assistant/agent/product-surface-reviewer.md +7 -0
- package/assets/init/.qfai/assistant/agent/qa-gatekeeper.md +29 -0
- package/assets/init/.qfai/assistant/agent/requirements-analyst.md +8 -0
- package/assets/init/.qfai/assistant/rule/communication.md +18 -8
- package/assets/init/.qfai/assistant/rule/constitution.md +5 -4
- package/assets/init/.qfai/assistant/rule/drift-protocol.md +72 -5
- package/assets/init/.qfai/assistant/rule/references/asset-authoring.md +72 -0
- package/assets/init/.qfai/assistant/rule/references/context-summary.md +30 -0
- package/assets/init/.qfai/assistant/rule/references/gate-failure-autorepair.md +42 -0
- package/assets/init/.qfai/assistant/rule/references/griller-recommendations.md +23 -0
- package/assets/init/.qfai/assistant/rule/references/host-backstops.md +60 -0
- package/assets/init/.qfai/assistant/rule/references/placeholder-scan.md +25 -0
- package/assets/init/.qfai/assistant/rule/references/reviewer-findings.md +41 -0
- package/assets/init/.qfai/assistant/rule/references/reviewer-remit.md +35 -0
- package/assets/init/.qfai/assistant/rule/references/worker-edit-boundary.md +48 -0
- package/assets/init/.qfai/assistant/rule/shared-skill-delegation-baseline.md +39 -162
- package/assets/init/.qfai/assistant/rule/shared-skill-operating-baseline.md +14 -145
- package/assets/init/.qfai/assistant/rule/stage-cost.md +1 -1
- package/assets/init/.qfai/assistant/rule/test-layers.md +42 -0
- package/assets/init/.qfai/assistant/rule/ui-definition-protocol.md +6 -1
- package/assets/init/.qfai/assistant/skill/qfai-configure/SKILL.md +11 -45
- package/assets/init/.qfai/assistant/skill/qfai-configure/references/principles.md +25 -0
- package/assets/init/.qfai/assistant/skill/qfai-discussion/SKILL.md +1 -1
- package/assets/init/.qfai/assistant/skill/qfai-discussion/references/discussion-completion-matrix.md +12 -9
- package/assets/init/.qfai/assistant/skill/qfai-discussion/references/ui-bearing-playbook.md +2 -4
- package/assets/init/.qfai/assistant/skill/qfai-discussion/references/ui_ux/platform_baselines.md +11 -0
- package/assets/init/.qfai/assistant/skill/qfai-discussion/references/ui_ux/review_audit_playbook.md +11 -0
- package/assets/init/.qfai/assistant/skill/qfai-discussion/references/ui_ux_best_practices.md +13 -42
- package/assets/init/.qfai/assistant/skill/qfai-discussion/templates/uiux/00_index.md +0 -16
- package/assets/init/.qfai/assistant/skill/qfai-grill/SKILL.md +1 -1
- package/assets/init/.qfai/assistant/skill/qfai-grilling/SKILL.md +16 -88
- package/assets/init/.qfai/assistant/skill/qfai-grilling/references/delegated-session.md +58 -0
- package/assets/init/.qfai/assistant/skill/qfai-grilling/references/session-record.md +42 -0
- package/assets/init/.qfai/assistant/skill/qfai-implement/SKILL.md +17 -4
- package/assets/init/.qfai/assistant/skill/qfai-implement/references/credential-reuse.md +9 -0
- package/assets/init/.qfai/assistant/skill/qfai-implement/references/cross-spec-ownership.md +41 -0
- package/assets/init/.qfai/assistant/skill/qfai-implement/references/oracle-strength.md +6 -1
- package/assets/init/.qfai/assistant/skill/qfai-implement/references/parallelization-policy.md +9 -1
- package/assets/init/.qfai/assistant/skill/qfai-implement/references/red-admissibility.md +47 -1
- package/assets/init/.qfai/assistant/skill/qfai-implement/references/ui-affecting.md +4 -3
- package/assets/init/.qfai/assistant/skill/qfai-maintain/SKILL.md +4 -4
- package/assets/init/.qfai/assistant/skill/qfai-migration-v1-to-v2/SKILL.md +16 -10
- package/assets/init/.qfai/assistant/skill/qfai-migration-v1-to-v2/references/migration-guide.md +10 -260
- package/assets/init/.qfai/assistant/skill/qfai-migration-v1-to-v2/references/migration-placement.md +273 -0
- package/assets/init/.qfai/assistant/skill/qfai-prototyping/SKILL.md +5 -4
- package/assets/init/.qfai/assistant/skill/qfai-prototyping/references/design-md-spec.md +14 -5
- package/assets/init/.qfai/assistant/skill/qfai-prototyping/references/generator-prompt.md +10 -0
- package/assets/init/.qfai/assistant/skill/qfai-prototyping/references/handoff.md +1 -1
- package/assets/init/.qfai/assistant/skill/qfai-prototyping/references/iteration-loop.md +3 -4
- package/assets/init/.qfai/assistant/skill/qfai-prototyping/references/review-payload-schema.md +12 -5
- package/assets/init/.qfai/assistant/skill/qfai-prototyping/references/reviewer-prompt.md +33 -4
- package/assets/init/.qfai/assistant/skill/qfai-run/SKILL.md +34 -36
- package/assets/init/.qfai/assistant/skill/qfai-run/references/evidence-delivery.md +322 -0
- package/assets/init/.qfai/assistant/skill/qfai-run/references/extraction.md +67 -24
- package/assets/init/.qfai/assistant/skill/qfai-run/references/operator-screens.md +246 -5
- package/assets/init/.qfai/assistant/skill/qfai-run/references/plan.md +29 -5
- package/assets/init/.qfai/assistant/skill/qfai-run/references/stage-points.md +43 -0
- package/assets/init/.qfai/assistant/skill/qfai-sdd/SKILL.md +5 -4
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/concrete-abstract-cycle.md +10 -1
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/contract-artifact-rules.md +22 -9
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/design-anti-patterns.md +41 -6
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/design-md-authoring.md +11 -5
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/design-md-brand-catalog.md +17 -2
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/requirements-decomposition.md +10 -2
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/sdd-execution-playbook.md +34 -9
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/sdd-phase-checklists.md +4 -4
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/sdd-quality-gate.md +2 -2
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/sdd-triage.md +177 -7
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/spec-traceability-rules.md +29 -5
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/ui-contract-guide.md +130 -1
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/ui-design-contract-normalization.md +4 -30
- package/assets/init/.qfai/assistant/skill/qfai-sdd/templates/change-request.md +39 -2
- package/assets/init/.qfai/assistant/skill/qfai-sdd/templates/contracts/db-contract.sample.sql +2 -2
- package/assets/init/.qfai/assistant/skill/qfai-sdd/templates/contracts/ui-contract.sample.yaml +52 -5
- package/assets/init/.qfai/assistant/skill/qfai-sdd/templates/spec/03_contract/cli/cli-NNNN-title.md +2 -2
- package/assets/init/.qfai/assistant/skill/qfai-sdd/templates/spec/03_contract/tech.md +1 -1
- package/assets/init/.qfai/assistant/skill/qfai-sdd/templates/spec/decisions.md +7 -0
- package/assets/init/.qfai/assistant/skill/qfai-triage/SKILL.md +30 -20
- package/assets/init/.qfai/assistant/skill/qfai-verify/SKILL.md +6 -5
- package/assets/init/.qfai/assistant/skill/qfai-verify/references/context-load.md +9 -6
- package/assets/init/.qfai/assistant/skill/qfai-verify/references/verify-output-contract.md +92 -13
- package/assets/init/.qfai/assistant/skill/web-research/SKILL.md +37 -31
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/brave-search/config.toml +2 -4
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/brave-search/mcp-config.json +9 -5
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/firecrawl/.mcp.json +1 -2
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/firecrawl/config.toml +3 -3
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/firecrawl/mcp-config.json +11 -8
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/playwright/config.toml +1 -1
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/playwright/mcp-config.json +7 -3
- package/assets/init/.qfai/assistant/step/common-design-md/STEP.md +17 -7
- package/assets/init/.qfai/assistant/step/common-gate-run/STEP.md +126 -13
- package/assets/init/.qfai/assistant/step/common-review-cycle/STEP.md +3 -2
- package/assets/init/.qfai/assistant/step/discussion-pack/STEP.md +1 -0
- package/assets/init/.qfai/assistant/step/discussion-research/STEP.md +2 -0
- package/assets/init/.qfai/assistant/step/discussion-uiux/STEP.md +12 -4
- package/assets/init/.qfai/assistant/step/implement-backport/STEP.md +1 -1
- package/assets/init/.qfai/assistant/step/implement-benchmark/STEP.md +7 -4
- package/assets/init/.qfai/assistant/step/implement-dep-bump/STEP.md +11 -1
- package/assets/init/.qfai/assistant/step/implement-diagnose/STEP.md +2 -0
- package/assets/init/.qfai/assistant/step/implement-oracle-parity/STEP.md +2 -2
- package/assets/init/.qfai/assistant/step/implement-quarantine/STEP.md +3 -3
- package/assets/init/.qfai/assistant/step/implement-refactor/STEP.md +2 -2
- package/assets/init/.qfai/assistant/step/implement-regression-fix/STEP.md +4 -3
- package/assets/init/.qfai/assistant/step/implement-retire/STEP.md +6 -3
- package/assets/init/.qfai/assistant/step/implement-revert/STEP.md +4 -3
- package/assets/init/.qfai/assistant/step/implement-scaffold/STEP.md +3 -3
- package/assets/init/.qfai/assistant/step/implement-seam/STEP.md +9 -6
- package/assets/init/.qfai/assistant/step/implement-stress-harness/STEP.md +1 -1
- package/assets/init/.qfai/assistant/step/implement-sweep/STEP.md +4 -3
- package/assets/init/.qfai/assistant/step/implement-tdd/STEP.md +42 -6
- package/assets/init/.qfai/assistant/step/implement-test-fix/STEP.md +2 -0
- package/assets/init/.qfai/assistant/step/implement-tooling/STEP.md +22 -2
- package/assets/init/.qfai/assistant/step/maintain-edit/STEP.md +18 -14
- package/assets/init/.qfai/assistant/step/prototyping-grill/STEP.md +4 -3
- package/assets/init/.qfai/assistant/step/prototyping-loop/STEP.md +4 -0
- package/assets/init/.qfai/assistant/step/prototyping-preflight/STEP.md +1 -3
- package/assets/init/.qfai/assistant/step/sdd-contract/STEP.md +11 -0
- package/assets/init/.qfai/assistant/step/sdd-flow/STEP.md +4 -0
- package/assets/init/.qfai/assistant/step/sdd-gate/STEP.md +4 -0
- package/assets/init/.qfai/assistant/step/sdd-story/STEP.md +10 -0
- package/assets/init/.qfai/assistant/step/sdd-triage/STEP.md +37 -11
- package/assets/init/.qfai/assistant/step/triage-answer/STEP.md +5 -4
- package/assets/init/.qfai/assistant/step/triage-close/STEP.md +33 -23
- package/assets/init/.qfai/assistant/step/triage-cluster/STEP.md +5 -3
- package/assets/init/.qfai/assistant/step/triage-decompose/STEP.md +2 -0
- package/assets/init/.qfai/assistant/step/triage-dedupe/STEP.md +4 -0
- package/assets/init/.qfai/assistant/step/triage-handoff/STEP.md +13 -4
- package/assets/init/.qfai/assistant/step/triage-investigate/STEP.md +8 -5
- package/assets/init/.qfai/assistant/step/triage-owned-cleanup/STEP.md +86 -0
- package/assets/init/.qfai/assistant/step/triage-request-info/STEP.md +2 -0
- package/assets/init/.qfai/assistant/step/triage-security-intake/STEP.md +6 -3
- package/assets/init/.qfai/assistant/step/verify-change-note/STEP.md +9 -5
- package/assets/init/.qfai/assistant/step/verify-commit/STEP.md +39 -6
- package/assets/init/.qfai/assistant/step/verify-external/STEP.md +5 -2
- package/assets/init/.qfai/assistant/step/verify-qfai-gate/STEP.md +10 -2
- package/assets/init/.qfai/assistant/step/verify-release-notes/STEP.md +1 -0
- package/assets/init/.qfai/assistant/step/verify-repeat-run/STEP.md +7 -5
- package/assets/init/.qfai/assistant/step/verify-repo-gate/STEP.md +136 -28
- package/assets/init/.qfai/waivers.yml +1 -1
- package/assets/init/root/.agents/rules/ai-readable-markdown.md +98 -0
- package/assets/init/root/.agents/rules/api-budget.md +191 -13
- package/assets/init/root/.agents/rules/documentation-clarity.md +192 -35
- package/assets/init/root/.agents/rules/grilling.md +4 -4
- package/assets/init/root/.agents/rules/interface-clarity.md +5 -5
- package/assets/init/root/.agents/rules/minimal-implementation.md +11 -3
- package/assets/init/root/.agents/rules/reminders.json +27 -14
- package/assets/init/root/.agents/rules/session-feedback.md +136 -0
- package/assets/init/root/.agents/rules/temporary-files.md +47 -5
- package/assets/init/root/.agents/rules/untrusted-content.md +3 -3
- package/assets/init/root/.agents/rules/user-questions.md +74 -36
- package/assets/init/root/.gitattributes +9 -0
- package/assets/init/root/.github/workflows/qfai-docs.yml +44 -12
- package/assets/init/root/.github/workflows/qfai-tests.yml +58 -15
- package/assets/init/root/.github/workflows/qfai-validate.yml +49 -42
- package/assets/init/root/AGENTS.md +23 -21
- package/assets/mdschema/story/03_contract/tech.mdschema.yml +7 -3
- package/assets/sandbox-templates/default-deny.yaml +9 -5
- package/assets/schemas/workflow/extraction.schema.json +85 -5
- package/assets/schemas/workflow/plan.schema.json +9 -2
- package/assets/scripts/check-mdschema.mjs +172 -5
- package/assets/uix-rev/comparison-review.md +1 -1
- package/assets/uix-rev/contracts-review.md +1 -2
- package/dist/cli/index.cjs +6499 -7688
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.mjs +6449 -7641
- package/dist/cli/index.mjs.map +1 -1
- package/dist/index.cjs +5548 -7823
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -666
- package/dist/index.d.ts +40 -666
- package/dist/index.mjs +5397 -7648
- package/dist/index.mjs.map +1 -1
- package/docs/MIGRATION-2.0.0.md +1 -1
- package/package.json +5 -7
- package/assets/init/root/CLAUDE.md +0 -45
|
@@ -18,9 +18,8 @@
|
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
The orchestrator writes the reviewer's payload for each `(UI contract, screen)` pair beside the
|
|
21
|
-
per-iteration `review.json` summary, from the first iteration on (schema
|
|
22
|
-
|
|
23
|
-
`references/reviewer-prompt.md`). That holds for a single-contract run as much
|
|
21
|
+
per-iteration `review.json` summary, from the first iteration on (the payload schema and the aggregation rule are
|
|
22
|
+
in the reviewer references the loop step names). That holds for a single-contract run as much
|
|
24
23
|
as for a multi-contract one.
|
|
25
24
|
|
|
26
25
|
The reviewer operates Playwright live. A screenshot or HTML snapshot is an
|
|
@@ -55,7 +54,7 @@ prototype. It is neutral with respect to AI behavior.
|
|
|
55
54
|
## Produced after the loop
|
|
56
55
|
|
|
57
56
|
- `.qfai/prototype/final/index.html` and `.qfai/prototype/final/handoff.json`.
|
|
58
|
-
|
|
57
|
+
The `prototyping-handoff` step defines its fields.
|
|
59
58
|
|
|
60
59
|
## Brand identity
|
|
61
60
|
|
package/assets/init/.qfai/assistant/skill/qfai-prototyping/references/review-payload-schema.md
CHANGED
|
@@ -7,9 +7,17 @@ and the user reads what it finds before confirming the prototype.
|
|
|
7
7
|
The schema is **closed**: any key not listed below is rejected. The
|
|
8
8
|
orchestrator checks each payload against it before writing it, and asks the
|
|
9
9
|
reviewer again for one that does not conform before the prototype is put to
|
|
10
|
-
the user. A near-miss (extra key, misspelled field
|
|
10
|
+
the user. A near-miss (extra key, misspelled field) fails the
|
|
11
11
|
whole file.
|
|
12
12
|
|
|
13
|
+
## Contents
|
|
14
|
+
|
|
15
|
+
- Path
|
|
16
|
+
- Shape (11 required top-level fields)
|
|
17
|
+
- Field rules
|
|
18
|
+
- Not accepted
|
|
19
|
+
- `sessionStatus` and the retry policy
|
|
20
|
+
|
|
13
21
|
## Path
|
|
14
22
|
|
|
15
23
|
```text
|
|
@@ -23,8 +31,8 @@ per-(UI contract × screen) artifact written for a review — no `.html`, no
|
|
|
23
31
|
`.png`, no `.interaction.json`.
|
|
24
32
|
|
|
25
33
|
The Reviewer's other result is the per-iteration summary
|
|
26
|
-
`iter-NN/review.json` (one per iteration, a different shape
|
|
27
|
-
|
|
34
|
+
`iter-NN/review.json` (one per iteration, a different shape, set by
|
|
35
|
+
the reviewer prompt). It is not a per-screen artifact and
|
|
28
36
|
is never read against this schema.
|
|
29
37
|
|
|
30
38
|
## Shape (11 required top-level fields)
|
|
@@ -91,8 +99,7 @@ These keys belong to the per-iteration summary, **not** to this payload.
|
|
|
91
99
|
Writing any of them here breaks the closed schema:
|
|
92
100
|
|
|
93
101
|
`iterIndex`, `reviewerId`, `proseCritique`, `pivotDirective`,
|
|
94
|
-
|
|
95
|
-
(use `softWarnings.timeBudget: boolean`).
|
|
102
|
+
and `evidenceRefs`.
|
|
96
103
|
|
|
97
104
|
## `sessionStatus` and the retry policy
|
|
98
105
|
|
|
@@ -18,12 +18,25 @@ put to the user. Explain observable defects and corrective actions in prose. A f
|
|
|
18
18
|
score never hides a blocking finding. Do not use numeric AC-pass or
|
|
19
19
|
transition-pass percentages as a substitute for the qualitative review.
|
|
20
20
|
|
|
21
|
+
## Contents
|
|
22
|
+
|
|
23
|
+
- Inputs
|
|
24
|
+
- Outputs — two files, two schemas
|
|
25
|
+
- Per-iteration summary (`iter-NN/review.json`)
|
|
26
|
+
- The four ordinal UX axes
|
|
27
|
+
- Diagnostic criteria
|
|
28
|
+
- Applying the four axes
|
|
29
|
+
- What blocks
|
|
30
|
+
- Layout anti-pattern matching (`lap-*`)
|
|
31
|
+
- pivotDirective rules
|
|
32
|
+
- Prose critique format (at most 500 English words, or 2500 Japanese/Chinese characters)
|
|
33
|
+
|
|
21
34
|
## Inputs
|
|
22
35
|
|
|
23
36
|
- The live prototype URL and declared `screens[]` routes from the UI contract.
|
|
24
37
|
Open each route in your own Playwright session and exercise its declared
|
|
25
38
|
primary tasks. Record `sessionStatus` and `retryCount` in the per-screen
|
|
26
|
-
payload according to
|
|
39
|
+
payload according to the closed per-screen payload schema.
|
|
27
40
|
- A screenshot or HTML snapshot, only when one was taken. Name any mandatory
|
|
28
41
|
input you did not receive in a finding.
|
|
29
42
|
- The layout anti-pattern registry the package ships.
|
|
@@ -55,7 +68,7 @@ below and are relative to the project root.
|
|
|
55
68
|
per-UI-contract subdirectory is mandatory for every run that declares UI
|
|
56
69
|
screens, including a run with one contract. Its schema is closed
|
|
57
70
|
(11 required top-level fields, unknown keys rejected) and lives in
|
|
58
|
-
|
|
71
|
+
the payload schema reference. Build it from that
|
|
59
72
|
reference, not from the block below.
|
|
60
73
|
2. **Per-iteration summary** —
|
|
61
74
|
`.qfai/prototype/iter-NN/review.json`, one per iteration. Its shape is
|
|
@@ -114,7 +127,7 @@ type Review = {
|
|
|
114
127
|
|
|
115
128
|
Fill `designMdViolations` yourself: one entry per distinct value the
|
|
116
129
|
prototype uses that root `DESIGN.md` does not declare, in the categories
|
|
117
|
-
|
|
130
|
+
the generator prompt lists.
|
|
118
131
|
|
|
119
132
|
## The four ordinal UX axes
|
|
120
133
|
|
|
@@ -155,7 +168,7 @@ count can support a finding, but cannot replace the live assessment.
|
|
|
155
168
|
| 5 | No catalogued anti-pattern is present | `lap-*`, below |
|
|
156
169
|
| 6 | Conformant, procured, restrained and consistent | below |
|
|
157
170
|
| 7 | Every declared `primary_task` walks | below |
|
|
158
|
-
| 8 | No text
|
|
171
|
+
| 8 | No text explains the interface, and the text shown is the contract's | `.agents/rules/interface-clarity.md` |
|
|
159
172
|
|
|
160
173
|
Criteria 1 to 4 are the procurement ladder read as questions, so a screen
|
|
161
174
|
cannot pass by a standard it was not built to.
|
|
@@ -201,6 +214,22 @@ Hint text survives only where a need was demonstrated, the control was
|
|
|
201
214
|
improved first and the need remained, and it is one sentence at most. Longer
|
|
202
215
|
means the question needs clarifying or splitting.
|
|
203
216
|
|
|
217
|
+
Compare the rendered text with the screen's UI contract in both directions. The
|
|
218
|
+
screen shows its `title`, the group headings of its `structure`, its labels and
|
|
219
|
+
the `supplements` it declares. A text shown that none of them declares is excess,
|
|
220
|
+
and a declared supplement that is not shown is an unmet need. The finding names
|
|
221
|
+
the screen, the task or state, the meaning that is duplicated or the need that is
|
|
222
|
+
unmet, and the text to remove or the control or structure to repair. Apply the
|
|
223
|
+
patterns of the section on copy that adds no meaning, which the loop step names; the
|
|
224
|
+
rest of the design anti-patterns list stays with the direction review.
|
|
225
|
+
|
|
226
|
+
A repair keeps what the task needs: a condition, cost, storage or transmission
|
|
227
|
+
destination, result, recovery step, the consequence of an action that cannot be
|
|
228
|
+
undone, and every label, accessible name, role and state. Moving that into a
|
|
229
|
+
tooltip or a placeholder is not a repair. After a repair, walk the task again at
|
|
230
|
+
the declared narrow and desktop widths, in the normal, empty, error, loading and
|
|
231
|
+
success states the screen has.
|
|
232
|
+
|
|
204
233
|
The counts are contract-relative. A screen declaring one primary task and
|
|
205
234
|
carrying forty controls is wrong; the same forty elsewhere may be right. The
|
|
206
235
|
denominator is in the contract, so no global threshold has to be invented.
|
|
@@ -12,15 +12,16 @@ mode: execution-focused
|
|
|
12
12
|
|
|
13
13
|
## /qfai-run - Change request entry
|
|
14
14
|
|
|
15
|
-
[DRIFT-PROTOCOL:
|
|
15
|
+
[DRIFT-PROTOCOL:REQUIRED]
|
|
16
16
|
|
|
17
|
-
The
|
|
18
|
-
`npx qfai workflow plan` for the plan they give, and runs its steps in order.
|
|
17
|
+
The CLI plans; this skill follows its steps in order.
|
|
19
18
|
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
19
|
+
- Read `references/extraction.md` to extract a request.
|
|
20
|
+
- Plan command and format: `references/plan.md`.
|
|
21
|
+
- Screens and questions: `references/operator-screens.md`.
|
|
22
|
+
- Release, decision and branch points: `references/stage-points.md`.
|
|
23
|
+
- Run preflight before planning, as `.qfai/assistant/rule/shared-skill-operating-baseline.md#canonical-qfai-launcher-mandatory` says.
|
|
24
|
+
If the launcher is missing or preflight fails, read `references/operator-screens.md` for recovery.
|
|
24
25
|
|
|
25
26
|
## What this skill never does
|
|
26
27
|
|
|
@@ -44,48 +45,42 @@ value but the three below plans nothing.
|
|
|
44
45
|
|
|
45
46
|
## Request kinds
|
|
46
47
|
|
|
48
|
+
- For independent targets under one goal, read `references/operator-screens.md`
|
|
49
|
+
before planning or switching during a wait.
|
|
47
50
|
- A change, a question, a proposal to decide or a report to close is planned.
|
|
48
51
|
A question plans a route that answers it and changes nothing. Text that is
|
|
49
52
|
not a request is not planned.
|
|
53
|
+
- A reply with a requested answer or result resumes the same step without a new
|
|
54
|
+
invocation, including failure. An independent new request is planned. Read
|
|
55
|
+
`references/operator-screens.md` for replies.
|
|
50
56
|
- `stop`: end the work at once and list every open decision as open.
|
|
51
57
|
- A request naming a stage skill: invoke that skill by name.
|
|
52
58
|
|
|
53
59
|
## The work
|
|
54
60
|
|
|
55
61
|
1. **Extract.** Read the request into an extraction as
|
|
56
|
-
`references/extraction.md` sets out,
|
|
62
|
+
`references/extraction.md` sets out, using its definition of acceptance.
|
|
63
|
+
Pass the extraction to
|
|
57
64
|
`npx qfai workflow plan --in <file>`, or `--in -` on standard input.
|
|
58
65
|
2. **Candidates.** When `plan` returns `candidates`, put one single-select
|
|
59
66
|
question, each option saying in the user's words what that route will do,
|
|
60
67
|
then run `npx qfai workflow plan --route <route>` for the chosen one.
|
|
61
|
-
3. **Scope.**
|
|
68
|
+
3. **Scope.** With two or more scopes, ask which to run as
|
|
69
|
+
`references/operator-screens.md` says, and run only its stages.
|
|
70
|
+
With one scope, no scopes, or a branch destination's plan, ask nothing and
|
|
71
|
+
run every stage.
|
|
62
72
|
4. **Announce.** Before the first stage, give the goal, the chosen stages in
|
|
63
73
|
order in plain words, and the files the work may change. Ask nothing. Then run
|
|
64
74
|
`common-policy-check` once. On a route that changes no file, one that
|
|
65
75
|
closes, answers or asks, it reads and reports and writes nothing.
|
|
66
76
|
5. **Run the stages.** Run each stage in plan order, and each of its steps in
|
|
67
|
-
order
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
runs without the approval, which authorizes no push, merge, tag or publication.
|
|
75
|
-
- **Decision point.** At a step `decisionPoints` names, put each critical
|
|
76
|
-
decision to the user through the structured question tool before
|
|
77
|
-
changing anything that depends on it. A decision is critical when it contradicts a
|
|
78
|
-
specification, a contract or a recorded decision, cannot be taken back, or
|
|
79
|
-
rests on product intent nothing written states. Take every other decision
|
|
80
|
-
yourself, ask nothing, and list it with its reason in the final report.
|
|
81
|
-
- **Branch point.** When a step `branchPoints` names reports an outcome
|
|
82
|
-
paired with one route, move there; with several, to the one the step
|
|
83
|
-
names; with `decision-table`, to the route `plan --in` gives the step's
|
|
84
|
-
new extraction. Take the destination's plan with
|
|
85
|
-
`npx qfai workflow plan --route <route>` at once: no later step of this
|
|
86
|
-
route runs. Any other outcome continues the route. Before the third move
|
|
87
|
-
and every one after it, ask the user, naming the destination in plain
|
|
88
|
-
words; `stop` ends the work. From a scope that leaves stages out, ask before any move.
|
|
77
|
+
order, as `.qfai/assistant/rule/shared-skill-operating-baseline.md#running-steps-mandatory` says.
|
|
78
|
+
When a step is short or passes without edits, read `references/operator-screens.md`.
|
|
79
|
+
Write artifacts yourself or delegate independent parallel work or review.
|
|
80
|
+
At each step, follow its plan's points in `references/stage-points.md`:
|
|
81
|
+
- **Release point.** Ask the user to approve the release before the step `releasePoint` names.
|
|
82
|
+
- **Decision point.** Put each critical decision at a step `decisionPoints` names to the user.
|
|
83
|
+
- **Branch point.** Move to the destination a step `branchPoints` names, and plan it at once.
|
|
89
84
|
6. **Review.** After a stage whose `review` is `spec`, `requirements-reviewer`
|
|
90
85
|
reviews, with `architecture-reviewer` when a contract changed; after one
|
|
91
86
|
whose `review` is `code`, `implementation-reviewer`.
|
|
@@ -102,6 +97,8 @@ value but the three below plans nothing.
|
|
|
102
97
|
## Under a no-question mode
|
|
103
98
|
|
|
104
99
|
Nothing is asked. The plan's narrowest scope, or the first candidate and its narrowest scope, is taken and reported as an assumption.
|
|
100
|
+
An uncovered question-only move to tracked-file repair instead stops that target
|
|
101
|
+
with a report and no tracked open question, as `references/stage-points.md` says.
|
|
105
102
|
A critical decision or a release point becomes one `open-questions.md` row,
|
|
106
103
|
the step stops before the change that depends on it, and the report lists the
|
|
107
104
|
decision as open. A third branch move, or one from a scope that leaves stages out, stops the work.
|
|
@@ -123,11 +120,7 @@ Follow `.qfai/assistant/rule/shared-skill-delegation-baseline.md`.
|
|
|
123
120
|
|
|
124
121
|
## Work Orders Summary
|
|
125
122
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
| Step | Role (sub-agent) | Agent instance | Task title | Input (refs) | Output (refs) | Status (PASS/REVISE/PENDING) |
|
|
129
|
-
| ---- | ---------------- | --------------- | ----------------- | ------------- | ------------- | ---------------------------- |
|
|
130
|
-
| 1 | `<role>` | `<instance id>` | `<part in words>` | The step file | The result | PASS/REVISE |
|
|
123
|
+
When parts ran in parallel, use the summary in `references/operator-screens.md`.
|
|
131
124
|
|
|
132
125
|
## Default Autopilot Policy
|
|
133
126
|
|
|
@@ -144,6 +137,11 @@ Where parts ran in parallel, report one row per part given to a sub-agent.
|
|
|
144
137
|
|
|
145
138
|
Follow `.qfai/assistant/rule/shared-skill-operating-baseline.md#completion-contract-shared`. **Smallest applicable smoke check** (this skill's override): the gates of the `verify-qfai-gate` and `verify-repo-gate` steps the chosen scope holds; a scope holding none runs no gate, and the report says so. A gate that cannot run is UNRUN, not a pass.
|
|
146
139
|
|
|
140
|
+
When the request requires evidence handover before session archive, read
|
|
141
|
+
`references/evidence-delivery.md` and complete its receiving proof first.
|
|
142
|
+
Missing access keeps the handover pending and originals retained. Ordinary
|
|
143
|
+
completion does not require an unsolicited upload.
|
|
144
|
+
|
|
147
145
|
project_memory:
|
|
148
146
|
|
|
149
147
|
- The user names no stage after the first request.
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# Evidence delivery
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- When delivery is required
|
|
6
|
+
- Identity and the ignored index
|
|
7
|
+
- Selection and privacy
|
|
8
|
+
- Native preflight
|
|
9
|
+
- Copy and archive
|
|
10
|
+
- Retained storage and receipt
|
|
11
|
+
- Independent receiver
|
|
12
|
+
- Failure and proof limits
|
|
13
|
+
|
|
14
|
+
## When delivery is required
|
|
15
|
+
|
|
16
|
+
Read this guide when a request requires evidence handover before a session is
|
|
17
|
+
archived. Complete that handover before archiving the session. Ordinary
|
|
18
|
+
completion does not require an unsolicited upload or an extra full verification
|
|
19
|
+
run solely to deliver evidence.
|
|
20
|
+
|
|
21
|
+
Use explicit selected regular files, an ignored human-readable index, standard
|
|
22
|
+
native tools and authorized retained storage. Keep originals until the named
|
|
23
|
+
recipient or receiving role has independently received and checked every
|
|
24
|
+
required item. A storage link or producer self-read is not that receipt.
|
|
25
|
+
|
|
26
|
+
This guide adds no QFAI command, exporter, storage service, machine schema or
|
|
27
|
+
runtime state. It does not change the plan, its gates or existing verdicts.
|
|
28
|
+
|
|
29
|
+
## Identity and the ignored index
|
|
30
|
+
|
|
31
|
+
Write the index in an ignored location outside the selected payload and keep
|
|
32
|
+
its destination in the stage report or session handoff. Record:
|
|
33
|
+
|
|
34
|
+
- target, scope, repository, branch and full source revision;
|
|
35
|
+
- observed worktree/index state and the fingerprint of the selected input;
|
|
36
|
+
- actual executable and build, command with separated argv, cwd, runtime,
|
|
37
|
+
input and time where observed;
|
|
38
|
+
- each selected relative name, expected byte length and SHA-256 digest;
|
|
39
|
+
- original results, excluded attempts and their original result and exclusion
|
|
40
|
+
reason, review identity, open work, owner and resume condition;
|
|
41
|
+
- sharing authority, exclusions, destination, receiving role and retention.
|
|
42
|
+
|
|
43
|
+
Use native Git observations such as `git rev-parse HEAD`,
|
|
44
|
+
`git status --porcelain=v1 --untracked-files=all` and
|
|
45
|
+
`git rev-parse --git-path index` to record the source and index. Where the index
|
|
46
|
+
exists, record its raw-byte digest too. Recheck the revision, index and selected
|
|
47
|
+
input before producing the archive. A changed revision/index or stale index
|
|
48
|
+
entry stops delivery until the intended source and required inventory are
|
|
49
|
+
established again. A dirty tree is disclosed with the selected-byte snapshot;
|
|
50
|
+
its commit alone cannot identify the actual input or build used by an old run.
|
|
51
|
+
|
|
52
|
+
Keep trusted expected selected sizes/digests, source identity and archive digest
|
|
53
|
+
outside the delivered bundle. Compare the index with those expectations. A
|
|
54
|
+
downloaded index cannot establish its own source or digest authority. Required
|
|
55
|
+
selected-file or independent source/archive identity that is UNKNOWN refuses
|
|
56
|
+
delivery; do not fabricate it from an unverified receipt.
|
|
57
|
+
|
|
58
|
+
Historical executable, build, command or time that was not observed stays
|
|
59
|
+
UNKNOWN. Known evidence may still be preserved, but unknown historical execution
|
|
60
|
+
does not prove verification. Keep old-source PASS separate from current FAIL,
|
|
61
|
+
UNRUN and delegated pending checks. Retain excluded failed attempts without
|
|
62
|
+
changing their result. No delivery completes failed or unrun required
|
|
63
|
+
verification, turns pending CI into PASS or relabels a review for another head.
|
|
64
|
+
Existing `verify.json` fields, scope and statuses stay unchanged.
|
|
65
|
+
|
|
66
|
+
## Selection and privacy
|
|
67
|
+
|
|
68
|
+
Select only the files needed to resume this target. Do not recursively discover
|
|
69
|
+
scratch, select a directory or copy a whole checkout. Give each required entry
|
|
70
|
+
a canonical relative name with `/` separators, a known expected byte length and
|
|
71
|
+
lowercase SHA-256 digest. Use a new owned staging root; keep the index and
|
|
72
|
+
archive outside it.
|
|
73
|
+
|
|
74
|
+
For portable names and unambiguous native listings, exclude control characters
|
|
75
|
+
and components ending in a dot or space. If a required original uses such a
|
|
76
|
+
name, review and identify a separately named copy before selecting it.
|
|
77
|
+
|
|
78
|
+
Review the selected names and contents, sharing authority and destination before
|
|
79
|
+
upload. Exclude credentials and unapproved private material. Record exclusions
|
|
80
|
+
without exposing withheld values. If a reviewed or redacted copy is needed,
|
|
81
|
+
identify it separately from the retained original and hash the bytes actually
|
|
82
|
+
delivered. Neither hashes nor the preflight detect all secrets, automatically
|
|
83
|
+
redact contents or establish privacy completeness.
|
|
84
|
+
|
|
85
|
+
The preflight below reads only the explicit selection. It refuses unsafe names,
|
|
86
|
+
missing or non-regular entries, linked root/ancestors/leaves, hardlinks,
|
|
87
|
+
duplicate normalized names, case collisions and wrong or changed byte identity.
|
|
88
|
+
It checks observations again during and after reading. These observations are
|
|
89
|
+
not an atomic snapshot or protection against every concurrent adversary.
|
|
90
|
+
|
|
91
|
+
## Native preflight
|
|
92
|
+
|
|
93
|
+
Save this single block verbatim as an owned temporary `.mjs` file. Run it with
|
|
94
|
+
the installed Node executable and separated argv:
|
|
95
|
+
|
|
96
|
+
`node <saved-preflight.mjs> <absolute-root> <relative-name> <decimal-byte-length> <lowercase-sha256> [more triples]`
|
|
97
|
+
|
|
98
|
+
Use the same block and trusted expected triples for source, staged copy and
|
|
99
|
+
receiver roots. There is no collection/receiver mode and no input from stdin.
|
|
100
|
+
The block changes no file. Exit 0 and `Verified N selected files.` mean only
|
|
101
|
+
that this selection passed these checks. Exit 1 refuses it; neither result
|
|
102
|
+
proves sharing authority, storage access, historical execution or handover.
|
|
103
|
+
|
|
104
|
+
```js
|
|
105
|
+
import fs from "node:fs";
|
|
106
|
+
import path from "node:path";
|
|
107
|
+
import { createHash } from "node:crypto";
|
|
108
|
+
|
|
109
|
+
function sameIdentity(left, right) {
|
|
110
|
+
return ["dev", "ino", "mode", "nlink", "size", "mtimeNs", "ctimeNs"].every(
|
|
111
|
+
(key) => left[key] === right[key],
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function sameDirectory(left, right) {
|
|
116
|
+
return ["dev", "ino", "mode"].every((key) => left[key] === right[key]);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function main() {
|
|
120
|
+
const [rootArg, ...args] = process.argv.slice(2);
|
|
121
|
+
if (!rootArg || !path.isAbsolute(rootArg) || !args.length || args.length % 3) {
|
|
122
|
+
throw new Error("Use an absolute root and complete name/size/digest triples.");
|
|
123
|
+
}
|
|
124
|
+
const root = path.resolve(rootArg);
|
|
125
|
+
const names = new Set();
|
|
126
|
+
const directories = new Map();
|
|
127
|
+
const entries = [];
|
|
128
|
+
|
|
129
|
+
function directory(name) {
|
|
130
|
+
const stat = fs.lstatSync(name, { bigint: true });
|
|
131
|
+
if (stat.isSymbolicLink() || !stat.isDirectory()) {
|
|
132
|
+
throw new Error("A selected path has a linked or non-directory component.");
|
|
133
|
+
}
|
|
134
|
+
const previous = directories.get(name);
|
|
135
|
+
if (previous && !sameDirectory(previous, stat)) {
|
|
136
|
+
throw new Error("A selected directory changed.");
|
|
137
|
+
}
|
|
138
|
+
directories.set(name, stat);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const parents = [];
|
|
142
|
+
for (let current = root; ; current = path.dirname(current)) {
|
|
143
|
+
parents.push(current);
|
|
144
|
+
if (path.dirname(current) === current) break;
|
|
145
|
+
}
|
|
146
|
+
parents.reverse().forEach(directory);
|
|
147
|
+
|
|
148
|
+
for (let offset = 0; offset < args.length; offset += 3) {
|
|
149
|
+
const [name, sizeText, digest] = args.slice(offset, offset + 3);
|
|
150
|
+
const parts = name.split("/");
|
|
151
|
+
if (
|
|
152
|
+
path.isAbsolute(name) ||
|
|
153
|
+
/[\\:\x00-\x1f\x7f]/u.test(name) ||
|
|
154
|
+
parts.some((part) => !part || part === "." || part === ".." || /[. ]$/u.test(part)) ||
|
|
155
|
+
!/^\d+$/u.test(sizeText) ||
|
|
156
|
+
!Number.isSafeInteger(Number(sizeText)) ||
|
|
157
|
+
!/^[a-f0-9]{64}$/u.test(digest)
|
|
158
|
+
) {
|
|
159
|
+
throw new Error("A selected name, expected size or digest is unsafe.");
|
|
160
|
+
}
|
|
161
|
+
const normalized = name.toLowerCase();
|
|
162
|
+
if (names.has(normalized)) {
|
|
163
|
+
throw new Error("Selected names are duplicated or collide by case.");
|
|
164
|
+
}
|
|
165
|
+
names.add(normalized);
|
|
166
|
+
let current = root;
|
|
167
|
+
for (const part of parts.slice(0, -1)) {
|
|
168
|
+
current = path.join(current, part);
|
|
169
|
+
directory(current);
|
|
170
|
+
}
|
|
171
|
+
const file = path.join(root, ...parts);
|
|
172
|
+
const stat = fs.lstatSync(file, { bigint: true });
|
|
173
|
+
const expectedSize = BigInt(sizeText);
|
|
174
|
+
if (stat.isSymbolicLink() || !stat.isFile() || stat.nlink !== 1n) {
|
|
175
|
+
throw new Error("A selected entry is linked, hardlinked or non-regular.");
|
|
176
|
+
}
|
|
177
|
+
if (stat.size !== expectedSize) throw new Error("A selected size changed.");
|
|
178
|
+
entries.push({ file, stat, expectedSize, digest });
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function recheckDirectories() {
|
|
182
|
+
for (const [name, before] of directories) {
|
|
183
|
+
const after = fs.lstatSync(name, { bigint: true });
|
|
184
|
+
if (!after.isDirectory() || after.isSymbolicLink() || !sameDirectory(before, after)) {
|
|
185
|
+
throw new Error("A selected directory changed.");
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const buffer = Buffer.alloc(64 * 1024);
|
|
191
|
+
for (const entry of entries) {
|
|
192
|
+
recheckDirectories();
|
|
193
|
+
const flags = fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0);
|
|
194
|
+
const descriptor = fs.openSync(entry.file, flags);
|
|
195
|
+
try {
|
|
196
|
+
const before = fs.fstatSync(descriptor, { bigint: true });
|
|
197
|
+
if (!before.isFile() || before.nlink !== 1n || !sameIdentity(entry.stat, before)) {
|
|
198
|
+
throw new Error("A selected entry changed before reading.");
|
|
199
|
+
}
|
|
200
|
+
const hash = createHash("sha256");
|
|
201
|
+
let size = 0n;
|
|
202
|
+
for (;;) {
|
|
203
|
+
const count = fs.readSync(descriptor, buffer, 0, buffer.length, null);
|
|
204
|
+
if (!count) break;
|
|
205
|
+
size += BigInt(count);
|
|
206
|
+
if (size > entry.expectedSize) throw new Error("A selected size changed.");
|
|
207
|
+
hash.update(buffer.subarray(0, count));
|
|
208
|
+
}
|
|
209
|
+
const after = fs.fstatSync(descriptor, { bigint: true });
|
|
210
|
+
const current = fs.lstatSync(entry.file, { bigint: true });
|
|
211
|
+
if (
|
|
212
|
+
!sameIdentity(before, after) ||
|
|
213
|
+
!sameIdentity(before, current) ||
|
|
214
|
+
size !== entry.expectedSize ||
|
|
215
|
+
hash.digest("hex") !== entry.digest
|
|
216
|
+
) {
|
|
217
|
+
throw new Error("Selected bytes or identity changed.");
|
|
218
|
+
}
|
|
219
|
+
recheckDirectories();
|
|
220
|
+
} finally {
|
|
221
|
+
fs.closeSync(descriptor);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
recheckDirectories();
|
|
225
|
+
for (const entry of entries) {
|
|
226
|
+
if (!sameIdentity(entry.stat, fs.lstatSync(entry.file, { bigint: true }))) {
|
|
227
|
+
throw new Error("A selected entry changed after reading.");
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
console.log(`Verified ${entries.length} selected files.`);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
try {
|
|
234
|
+
main();
|
|
235
|
+
} catch (error) {
|
|
236
|
+
console.error(`Evidence preflight refused: ${error.message}`);
|
|
237
|
+
process.exitCode = 1;
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Copy and archive
|
|
242
|
+
|
|
243
|
+
After source preflight succeeds, copy only those selected files to the new owned
|
|
244
|
+
staging root. Use a native literal-path copy or Node's `fs.copyFileSync`; create
|
|
245
|
+
only their listed parent directories. Do not decode, rewrite or normalize
|
|
246
|
+
binary data, encoding markers, LF or CRLF. Re-run the exact preflight block on
|
|
247
|
+
staging with the trusted source expectations immediately before native tar.
|
|
248
|
+
If anything changes or cannot be read, stop before archive and keep originals.
|
|
249
|
+
|
|
250
|
+
Use the installed native tar executable with separated argv, for example:
|
|
251
|
+
|
|
252
|
+
- create: `tar -cf <absolute-bundle.tar> -C <absolute-staging-root> ./<selected-name> ...`
|
|
253
|
+
- list: `tar -tf <absolute-bundle.tar>`
|
|
254
|
+
- extract: `tar -xf <absolute-bundle.tar> -C <fresh-absolute-receiver-root>`
|
|
255
|
+
|
|
256
|
+
Prefix each selected name with `./` to avoid option or archive-inclusion
|
|
257
|
+
interpretation. Select no directory and use no wildcard or shell interpolation.
|
|
258
|
+
Check the actual listing against the exact expected member set: each required
|
|
259
|
+
name occurs once, with no unexpected or missing member. Record the actual
|
|
260
|
+
executable/version, argv, cwd, platform, exit/signal and stdout/stderr. A missing
|
|
261
|
+
tool or failed command is not successful production. Different native tar
|
|
262
|
+
implementations need not produce identical archive container bytes.
|
|
263
|
+
|
|
264
|
+
Calculate the produced archive's raw-byte SHA-256 and record it with the trusted
|
|
265
|
+
source and selected expectations outside the archive. Archive digest identity
|
|
266
|
+
alone does not prove file provenance, privacy or recipient access.
|
|
267
|
+
|
|
268
|
+
## Retained storage and receipt
|
|
269
|
+
|
|
270
|
+
Before upload, establish existing authority for this target and payload,
|
|
271
|
+
destination privacy, the named recipient or receiving role, required access and
|
|
272
|
+
retention. A visible storage link grants none of these. Use an existing
|
|
273
|
+
authorized retained channel; do not create a paid service or publish private raw
|
|
274
|
+
evidence by assumption. Preserve actual upload results and artifact identity.
|
|
275
|
+
|
|
276
|
+
The ignored receiving receipt records who received the evidence, retrieval time,
|
|
277
|
+
destination and artifact identity, retrieved items, independently checked source
|
|
278
|
+
and archive identity, every required size/digest result and missing evidence.
|
|
279
|
+
Keep its reference in the stage report or handoff. A required item or receipt
|
|
280
|
+
that is unavailable, expired, denied, incomplete or mismatched leaves handover
|
|
281
|
+
pending, records the blocker and resume condition, and retains originals.
|
|
282
|
+
|
|
283
|
+
## Independent receiver
|
|
284
|
+
|
|
285
|
+
The receiver independently retrieves every required item from retained storage;
|
|
286
|
+
producer self-read or index visibility is insufficient. Supply trusted source,
|
|
287
|
+
archive digest and selected-file expectations through a separate authorized
|
|
288
|
+
channel. Check the archive's actual raw-byte digest and source identity against
|
|
289
|
+
those expectations before extraction. Refuse a mismatched or unknown archive.
|
|
290
|
+
|
|
291
|
+
Extract only this known-safe producer archive into a fresh owned receiving root.
|
|
292
|
+
This procedure does not safely extract arbitrary third-party archives. Check
|
|
293
|
+
the exact member set and re-run the same preflight on the extracted regular
|
|
294
|
+
files with the trusted expected triples. Compare the index's target/source and
|
|
295
|
+
inventory with the separately supplied expectations. Missing, duplicated,
|
|
296
|
+
unexpected, linked or altered members do not produce an accepted receipt.
|
|
297
|
+
|
|
298
|
+
Only the named recipient's actual complete receiving proof allows the requested
|
|
299
|
+
handover to complete before real session archive. Local producer checks cannot
|
|
300
|
+
stand in for it. Preserve unrelated receiver contents and originals when proof
|
|
301
|
+
fails; do not destroy or silently replace them to make the receipt pass.
|
|
302
|
+
|
|
303
|
+
## Failure and proof limits
|
|
304
|
+
|
|
305
|
+
On unsafe selection, changed source or index, missing evidence, unknown required
|
|
306
|
+
identity, denied access, expiry or mismatched bytes, stop dependent delivery and
|
|
307
|
+
archive. Name the observed blocker, missing item, owner and resume condition.
|
|
308
|
+
Keep actual failure output and originals. Required verification FAIL, UNRUN or
|
|
309
|
+
pending remains incomplete even if some evidence was successfully delivered.
|
|
310
|
+
|
|
311
|
+
Generic capability acceptance requires actual native Linux and Windows
|
|
312
|
+
producers and separate Linux and Windows hosted receivers. Each receiver must
|
|
313
|
+
retrieve both retained producer artifacts and independently check their bytes,
|
|
314
|
+
digests and source identity: all four transfer directions need actual proof.
|
|
315
|
+
Executing only the instructions or reading one's own output is insufficient.
|
|
316
|
+
|
|
317
|
+
That controlled CI receipt proves the tested capability. It does not establish
|
|
318
|
+
this session's real successor access, long-term retention, a session archive or
|
|
319
|
+
general sharing permission. Historical metadata remains UNKNOWN where absent.
|
|
320
|
+
The preflight is neither an automatic secret scanner, an exporter nor an atomic
|
|
321
|
+
concurrent-adversary guarantee. Native archives are not a general safe restore
|
|
322
|
+
engine. Report these limits with the actual observations.
|