升级Trellis并精简项目知识(09-05-trellis-upgrade-rule-cleanup)

更新Trellis适配、任务归属与归档失败恢复,精简技能入口和知识读取规则。
保留权限、证据、事务及独立复核合同;纳入对应任务及已完成复核记录。
仅本地提交,不启用新平台适配,不推送或部署。
这个提交包含在:
2026-09-19 13:10:06 +08:00
父节点 b1d25d3c99
当前提交 729d90576f
共修改 25 个文件,包含 550 行新增和 1328 行删除
@@ -1,105 +1,21 @@
# Code Reuse Thinking Guide
> **Purpose**: Stop and think before creating new code - does it already exist?
Consult when adding a helper/component or changing behavior shared by multiple
consumers. Search the relevant source and tests with `rg` before creating a
second implementation; widen the search when ownership is uncertain.
---
## Decide From The Contract
## The Problem
- Compare responsibilities, inputs, failure behavior, permissions and lifecycle, not only similar syntax or visual shape.
- Reuse or extend an existing owner when the semantics agree. Keep distinct rules separate when combining them creates flags, coupling or misleading names.
- Share constants only when they represent the same business fact. A fixed repetition count or similarity percentage does not justify an abstraction.
- For a shared change, identify callers and assert the affected behaviors, including exceptions. After a batch edit, check for missed consumers and accidental out-of-scope changes.
**Duplicated code is the #1 source of inconsistency bugs.**
## Asymmetric Producers
When you copy-paste or rewrite existing logic:
- Bug fixes don't propagate
- Behavior diverges over time
- Codebase becomes harder to understand
---
## Before Writing New Code
### Step 1: Search First
```bash
# Search for similar function names
grep -r "functionName" .
# Search for similar logic
grep -r "keyword" .
```
### Step 2: Ask These Questions
| Question | If Yes... |
|----------|-----------|
| Does a similar function exist? | Use or extend it |
| Is this pattern used elsewhere? | Follow the existing pattern |
| Could this be a shared utility? | Create it in the right place |
| Am I copying code from another file? | **STOP** - extract to shared |
---
## Common Duplication Patterns
### Pattern 1: Copy-Paste Functions
**Bad**: Copying a validation function to another file
**Good**: Extract to shared utilities, import where needed
### Pattern 2: Similar Components
**Bad**: Creating a new component that's 80% similar to existing
**Good**: Extend existing component with props/variants
### Pattern 3: Repeated Constants
**Bad**: Defining the same constant in multiple files
**Good**: Single source of truth, import everywhere
---
## When to Abstract
**Abstract when**:
- Same code appears 3+ times
- Logic is complex enough to have bugs
- Multiple people might need this
**Don't abstract when**:
- Only used once
- Trivial one-liner
- Abstraction would be more complex than duplication
---
## After Batch Modifications
When you've made similar changes to multiple files:
1. **Review**: Did you catch all instances?
2. **Search**: Run grep to find any missed
3. **Consider**: Should this be abstracted?
---
## Gotcha: Asymmetric Mechanisms Producing Same Output
**Problem**: When two different mechanisms must produce the same file set (e.g., recursive directory copy for init vs. manual `files.set()` for update), structural changes (renaming, moving, adding subdirectories) only propagate through the automatic mechanism. The manual one silently drifts.
**Symptom**: Init works perfectly, but update creates files at wrong paths or misses files entirely.
**Prevention checklist**:
- [ ] When migrating directory structures, search for ALL code paths that reference the old structure
- [ ] If one path is auto-derived (glob/copy) and another is manually listed, the manual one needs updating
- [ ] Add a regression test that compares outputs from both mechanisms
---
## Checklist Before Commit
- [ ] Searched for existing similar code
- [ ] No copy-pasted logic that should be shared
- [ ] Constants defined in one place
- [ ] Similar patterns follow same structure
When automatic discovery/copy and a manually listed producer promise the same
output (for example init/update, screen/export or live/snapshot inputs), a
rename or added field can update only one side. Inspect both producers and
compare their observable output contract. Prefer a focused parity regression
over another copied list; do not assume generated output proves every producer
was exercised.
@@ -1,162 +1,46 @@
# Cross-Layer Thinking Guide
> **Purpose**: Think through data flow across layers before implementing.
Use for changes crossing data, authority or state boundaries. Trace the affected
path from input through transformation/storage to display or export. Identify
consumers and the format, ownership, errors and invariants at each boundary.
Do not require a diagram or new document when a short task note suffices.
---
## Validation And Round Trips
## The Problem
Client validation helps the user; the server still enforces authentication,
authorization and untrusted input. Mutable business facts may need rechecking
under the transaction/lock that protects the write. Reuse pure validation rules
where semantics agree, but never remove a trust-boundary check merely because
another layer validated earlier.
**Most bugs happen at layer boundaries**, not within layers.
Check null/omitted/empty distinctions, dates/time zones, precision, serialization
and error handling on affected consumers. Verify meaningful round trips and
negative cases; test depth follows the changed contract, not a fixed layer count.
The owning domain spec defines exact business behavior.
Common cross-layer bugs:
- API returns format A, frontend expects format B
- Database stores X, service transforms to Y, but loses data
- Multiple layers implement the same logic differently
## Generated Runtime Inputs
---
For generated files that are also parsed at runtime, identify readers as well
as writers. Workflow tag/platform markers outside a managed block may affect
phase routing even when the block itself updates correctly.
## Before Implementing Cross-Layer Features
In this installed project, use the pinned target CLI, preserve overlays and
exercise the actual context/hook parsers; see
[upgrade compatibility](../hyb-oa/project-governance.md#scenario-trellis-project-upgrade-compatibility).
Only an authorized upstream-template task should modify other platform copies
or test upstream init/update generation with older pristine fixtures. Do not
assume this repository contains `src/templates` or enable other platforms.
### Step 1: Map the Data Flow
## Probe-Dependent Modes
Draw out how data moves:
When a mode depends on an external probe, check normal, non-interactive and
shortcut paths. Distinguish missing resources from transient failures; fail
clearly or retry within the authorized budget, never silently switch modes
after a timeout or transport error. Preserve that error
quality in downstream helpers and reset cached state when the source changes.
```
Source → Transform → Store → Retrieve → Transform → Display
```
For each arrow, ask:
- What format is the data in?
- What could go wrong?
- Who is responsible for validation?
### Step 2: Identify Boundaries
| Boundary | Common Issues |
|----------|---------------|
| API ↔ Service | Type mismatches, missing fields |
| Service ↔ Database | Format conversions, null handling |
| Backend ↔ Frontend | Serialization, date formats |
| Component ↔ Component | Props shape changes |
### Step 3: Define Contracts
For each boundary:
- What is the exact input format?
- What is the exact output format?
- What errors can occur?
---
## Common Cross-Layer Mistakes
### Mistake 1: Implicit Format Assumptions
**Bad**: Assuming date format without checking
**Good**: Explicit format conversion at boundaries
### Mistake 2: Scattered Validation
**Bad**: Validating the same thing in multiple layers
**Good**: Validate once at the entry point
### Mistake 3: Leaky Abstractions
**Bad**: Component knows about database schema
**Good**: Each layer only knows its neighbors
---
## Checklist for Cross-Layer Features
Before implementation:
- [ ] Mapped the complete data flow
- [ ] Identified all layer boundaries
- [ ] Defined format at each boundary
- [ ] Decided where validation happens
After implementation:
- [ ] Tested with edge cases (null, empty, invalid)
- [ ] Verified error handling at each boundary
- [ ] Checked data survives round-trip
---
## Cross-Platform Template Consistency
In Trellis, command templates (e.g., `record-session.md`) exist in **multiple platforms** with identical or near-identical content. This is a cross-layer boundary.
### Checklist: After Modifying Any Command Template
- [ ] Find all platforms with the same command: `find src/templates/*/commands/trellis/ -name "<command>.*"`
- [ ] Update all platform copies (Markdown `.md` and TOML `.toml`)
- [ ] For Gemini TOML: adapt line continuations (`\\` vs `\`) and triple-quoted strings
- [ ] Run `/trellis:check-cross-layer` to verify nothing was missed
**Real-world example**: Updated `record-session.md` in Claude to use `--mode record`, but forgot iFlow, Kilo, OpenCode, and Gemini — caught by cross-layer check.
---
## Generated Runtime Template Upgrade Consistency
Some generated files are both documentation and runtime input. In Trellis,
`.trellis/workflow.md` is parsed by `get_context.py`, `workflow_phase.py`,
SessionStart filters, and per-turn hooks. Template changes must be validated
against both fresh init and upgrade paths.
### Checklist: After Modifying A Runtime-Parsed Template
- [ ] Identify every runtime parser that reads the template, not just the file
writer that installs it
- [ ] Check whether relevant syntax lives outside obvious managed regions
such as tag blocks
- [ ] Verify fresh `init` output and a versioned `update` scenario that writes
the older `.trellis/.version`
- [ ] Add an upgrade regression using an older pristine template fixture, then
assert the installed file reaches the current packaged shape
- [ ] Update the backend spec that owns the runtime contract
**Real-world example**: Codex inline mode changed workflow platform markers from
`[Codex]` / `[Kilo, Antigravity, Windsurf]` to `[codex-sub-agent]` /
`[codex-inline, Kilo, Antigravity, Windsurf]`. Fresh init was correct, but
`trellis update` only merged `[workflow-state:*]` blocks and preserved stale
markers outside those blocks. Result: upgraded projects got new hook scripts
but old workflow routing, so `get_context.py --mode phase --platform codex`
could return empty Phase 2.1 detail.
---
## Mode-Detection Probe Checklist
When a CLI auto-detects a mode by probing a remote resource (e.g., checking if `index.json` exists to decide marketplace vs direct download):
### Before implementing:
- [ ] Probe runs in **ALL** code paths that use the result (interactive, `-y`, `--flag` combos)
- [ ] 404 vs transient error are distinguished — don't treat both as "not found"
- [ ] Transient errors **abort or retry**, never silently switch modes
- [ ] Shared state (caches, prefetched data) is **reset** when context changes (e.g., user switches source)
- [ ] **Shortcut paths** (e.g., `--template` skipping picker) must have the same error-handling quality as the probed path — check that downstream functions don't call catch-all wrappers
### After implementing:
- [ ] Trace every path from probe result to the mode-decision branch — no fallthrough
- [ ] External format contracts (giget URI, raw URLs) are tested or at least documented as comments
- [ ] Metadata reads consume a complete response or use a streaming parser — never parse a fixed-size prefix as full JSON
- [ ] When reconstructing a composite identifier from parsed parts, verify **all** fields are included and in the **correct position** (e.g., `provider:repo/path#ref` not `provider:repo#ref/path`)
- [ ] Verify that **action functions** called after a shortcut don't internally use the old catch-all fetch — they must use the probe-quality variant when error distinction matters
**Real-world example**: Custom registry flow had 8 bugs across 3 review rounds: (1) probe only ran in interactive mode, (2) transient errors fell through to wrong mode, (3) giget URI had `#ref` in wrong position, (4) prefetched templates leaked across source switches, (5) `--template` shortcut bypassed probe but `downloadTemplateById` internally used catch-all `fetchTemplateIndex`, turning timeouts into "Template not found".
**Real-world example**: Agent-session update hints fetched npm `latest` metadata with `response.read(4096)` and then parsed it as complete JSON. The `@mindfoldhq/trellis` package metadata exceeded 4 KB, so the JSON was truncated, parse failed silently, and the first session injection showed no update hint. Fix: read the complete response before parsing, and add a regression where `version` is followed by an 8 KB metadata tail.
---
## When to Create Flow Documentation
Create detailed flow docs when:
- Feature spans 3+ layers
- Multiple teams are involved
- Data format is complex
- Feature has caused bugs before
Parse complete metadata or use a real streaming parser; a fixed-length prefix
is not a complete JSON document. For reconstructed identifiers, preserve all
fields and their ordering (such as path before fragment). Exercise a large
metadata response and failure/shortcut cases only when those mechanisms are
part of the change. Do not contact real external systems merely to read this guide.
+10 -68
查看文件
@@ -1,72 +1,14 @@
# Thinking Guides
> **Purpose**: Expand your thinking to catch things you might not have considered.
Use a guide only when its trigger applies and its relevant context is not
already loaded. Stable implementation contracts remain in the domain specs;
these guides help locate the questions that matter.
---
| Guide | Trigger |
| --- | --- |
| [Code reuse](./code-reuse-thinking-guide.md) | A new helper/component, repeated behavior, or a shared constant/contract change |
| [Cross-layer behavior](./cross-layer-thinking-guide.md) | Data, authority or state crosses a boundary; multiple consumers depend on a change |
## Why Thinking Guides?
**Most bugs and tech debt come from "didn't think of that"**, not from lack of skill:
- Didn't think about what happens at layer boundaries → cross-layer bugs
- Didn't think about code patterns repeating → duplicated code everywhere
- Didn't think about edge cases → runtime errors
- Didn't think about future maintainers → unreadable code
These guides help you **ask the right questions before coding**.
---
## Available Guides
| Guide | Purpose | When to Use |
|-------|---------|-------------|
| [Code Reuse Thinking Guide](./code-reuse-thinking-guide.md) | Identify patterns and reduce duplication | When you notice repeated patterns |
| [Cross-Layer Thinking Guide](./cross-layer-thinking-guide.md) | Think through data flow across layers | Features spanning multiple layers |
---
## Quick Reference: Thinking Triggers
### When to Think About Cross-Layer Issues
- [ ] Feature touches 3+ layers (API, Service, Component, Database)
- [ ] Data format changes between layers
- [ ] Multiple consumers need the same data
- [ ] You're not sure where to put some logic
→ Read [Cross-Layer Thinking Guide](./cross-layer-thinking-guide.md)
### When to Think About Code Reuse
- [ ] You're writing similar code to something that exists
- [ ] You see the same pattern repeated 3+ times
- [ ] You're adding a new field to multiple places
- [ ] You are changing a shared constant or configuration contract
- [ ] **You're creating a new utility/helper function** ← Search first!
→ Read [Code Reuse Thinking Guide](./code-reuse-thinking-guide.md)
---
## Reference Checks By Risk
Before changing shared contracts, cross-layer constants or configuration, inspect their consumers. A local literal or wording correction does not require a repository-wide search. Read these guides only when the task matches their triggers; do not repeat an unchanged checklist every turn.
---
## How to Use This Directory
1. **Before coding**: Skim the relevant thinking guide
2. **During coding**: If something feels repetitive or complex, check the guides
3. **After bugs**: Add new insights to the relevant guide (learn from mistakes)
---
## Contributing
Found a new "didn't think of that" moment? Add it to the relevant guide.
---
**Core Principle**: 30 minutes of thinking saves 3 hours of debugging.
Search affected consumers for a shared-contract change. A local wording or
literal correction does not require a full-repository search. Add a reusable
insight at its existing owner; keep one-off findings in the task.
+99 -188
查看文件
@@ -2,276 +2,187 @@
## Source Docs
Start from `docs/文档索引.md` and `docs/文档事实源状态矩阵.md`.
Use `docs/文档索引.md` and `docs/文档事实源状态矩阵.md` to locate the current fact owner.
## Rules
- Prefer updating existing fact sources, module specs, manuals, evidence docs
or the current Trellis task.
- New documents need a reason and must be registered in both the index and
status matrix.
- Old Issue CSV files are historical audit evidence and should not be rewritten
unless the current Trellis task explicitly calls for a legacy/export update.
- For generated evidence, store report paths and conclusions, not raw secrets,
raw payloads, full account identifiers, invoice originals or confidential
business content.
- Update the existing fact source, module spec, manual or task. A new document needs a distinct purpose and registration in both the docs index and status matrix.
- Keep a verified reusable rule in its owning section; keep run chronology, counts, candidate hashes and unresolved hypotheses in task/evidence. Consolidate repetition without losing unique conditions, exceptions or references. If there is no new reusable lesson, no spec edit is needed; a fixed seven-section layout is not required unless the task/delivery contract requires it.
- Preserve historical Issue CSVs, findings and original receipts. New evidence adds a dated/sourced delta; it does not rewrite the old result. A matching selected-code digest does not establish whole-tree or publication coverage.
- Record relative report references and safe conclusions, not raw payloads, secrets, full accounts, invoice originals or confidential business content. Static validation, runtime behavior, independent review and public/real-data verification remain distinct.
## Scenario: Registered Local Evidence Integrity
### 1. Scope / Trigger
Protect the 14 historical screenshots registered in the archived 07-18
small-team internal-readiness evidence table. Not being an automated snapshot
baseline does not make human-reviewed, digest-registered evidence disposable.
small-team internal-readiness evidence table. Human-reviewed digest-registered
artifacts remain evidence even when automated snapshot tests do not read them.
### 2. Signatures
`node scripts/qa/check-trellis-governance.mjs` calls `validateRegisteredEvidence`.
The code-owned registry supplies document, artifact directory and expected count;
the document's `截图 | SHA-256` table supplies filenames and approved hashes.
Its code-owned registry defines document, artifact directory and expected count;
the document's `截图 | SHA-256` table defines filenames and approved hashes.
### 3. Contracts
Validate regular local files without following symlink artifacts or ancestor
redirects. Preserve original documents/hashes. Before restoring an accidentally
overwritten artifact, preserve the new runtime copy and its digest separately.
Do not remove registered evidence from the index merely because tests never read it.
Historical private restore-runner candidate hashes without a public repository
file mapping are not local-file checks; do not fetch private/production inputs
or claim universal verification of every SHA literal in Trellis documents.
Require regular local files, without artifact symlinks or ancestor redirects.
Preserve the registered documents/hashes. Before restoring an overwritten file,
save the runtime copy and its digest separately. Do not unregister evidence to
make a check pass. Private restore-candidate hashes without a public repository
file mapping are outside this local check; do not fetch private/production inputs
or claim every historical SHA was verified.
### 4. Validation / Error Matrix
Missing document/table/file, changed digest, invalid row/path, duplicate entry,
symlink or reduced registered count is a governance error. A matching table
reports the exact number verified; no silent table-shrink acceptance is allowed.
symlink or reduced registered count fails governance. A match reports the exact
verified count; silently shrinking the table is not an acceptable repair.
### 5. Good / Base / Bad
Good: verify 14/14 archived hashes while new screenshots go to isolated run roots.
Base: local governance verifies registered public artifacts, with scope explicit.
Bad: ignore all output paths, silently replace archived hashes, or call unverifiable
private historical candidates locally verified.
Verify the registered 14/14 separately from new isolated screenshots. Never
replace approved hashes with runtime outputs or claim unmapped private evidence
was locally checked.
### 6. Tests Required
`node --test scripts/qa/tests/registered-evidence.test.mjs` covers intact evidence,
overwrites, missing files/tables/rows, duplicate rows, unsafe paths and symlinks.
Visual path and full-repository snapshot tests separately prevent the producer
from overwriting history and detect tracked mutations even when already dirty.
`node --test scripts/qa/tests/registered-evidence.test.mjs`: intact evidence,
overwrite/missing document/table/file/row, duplicate rows, unsafe paths and
symlinks. Visual-output isolation and repository snapshot tests separately check
the producer and tracked mutations, including an already dirty checkout.
### 7. Wrong / Correct
Wrong: selected source digest unchanged, therefore the worktree is unchanged.
Correct: report selected-source and repository/index facts separately; tracked
output remains subject to the same whole-repository integrity requirements.
Report selected-source, whole-repository and index integrity separately; an
unchanged selected-source digest does not prove the worktree is unchanged.
## Scenario: Finding Lifecycle And Audit Closeout
### 1. Scope / Trigger
- Trigger: a review, audit or trial-run task records findings and later code,
deployment or external evidence changes their current state.
- Applies to Trellis PRDs, review reports, finding ledgers and management
summaries.
Use when later code, deployment or external evidence changes a recorded review,
audit or trial-run finding's current disposition.
### 2. Signatures
- Canonical ledger fields: `findingId`, `dimension`, `discoverySeverity`,
`confidence`, `discoveryStatus`, `remediationStatus`, `deploymentStatus`,
`externalVerificationStatus`, `evidenceRef`, `businessImpact`,
`controlObjective`, `safeVerification`, `followUpWorkPackage`.
- Delta fields: `discoveryCommit`, `reviewedCommit`, changed-commit list,
validation command, result and explicit environment boundary.
Canonical ledger fields: `findingId`, `dimension`, `discoverySeverity`,
`confidence`, `discoveryStatus`, `remediationStatus`, `deploymentStatus`,
`externalVerificationStatus`, `evidenceRef`, `businessImpact`, `controlObjective`,
`safeVerification`, `followUpWorkPackage`. A delta records `discoveryCommit`,
`reviewedCommit`, changed commits, command/result and environment boundary.
### 3. Contracts
- Preserve the discovery baseline, discovery severity and discovery status.
Later remediation must add a delta; it must not rewrite history as if the
finding never existed.
- Record remediation, deployment and external-behavior verification as three
independent states. A local test pass does not prove deployment, and a
deployed build marker does not prove role-specific or real-device behavior.
- A closeout task must have one canonical finding ledger. Component reports
may retain their original wording, but duplicate IDs and reclassified items
must point to the canonical ledger.
- When HEAD moves after discovery, record the exact old and new commits,
classify the delta and rerun the closeout gates. Do not relabel an old report
as evidence for the new HEAD.
- Use repo-relative evidence references and synthetic fixtures. Unknown or
unauthorized deployment, public, production-data and real-device checks stay
explicit as pending or externally gated.
Preserve discovery baseline/severity/status. Maintain one canonical finding
ledger per closeout; duplicate or reclassified component findings retain source
references and map to exactly one canonical entry. Record remediation,
deployment and external behavior independently: local PASS does not establish
deployment, and a build marker does not establish role/device behavior.
When HEAD changes, identify old/new commits, classify the delta and rerun the
applicable closeout gates; never relabel old reports as evidence for new inputs.
Use relative evidence refs and synthetic fixtures. Unknown or unauthorized
production/public/real-device checks remain explicitly pending or externally gated.
### 4. Validation & Error Matrix
- Local fix tested, not deployed -> remediation may pass; deployment remains
pending and external behavior remains pending when applicable.
- Finding open with no fix artifact -> deployment is `NO_FIX_TO_DEPLOY`, not
`DEPLOYMENT_PENDING`.
- Static/tooling-only finding -> deployment may be `NOT_APPLICABLE`; the
remediation state still records whether the contract itself is fixed.
- Duplicate component finding -> preserve its source reference and map it to
exactly one canonical ledger entry.
| Condition | Recorded state |
| --- | --- |
| Local fix verified, not deployed | Remediation may pass; deployment and applicable external behavior remain pending |
| Open finding with no fix artifact | `NO_FIX_TO_DEPLOY`, not `DEPLOYMENT_PENDING` |
| Static/tooling-only finding | Deployment may be `NOT_APPLICABLE`; record remediation independently |
| External verification not required | `NOT_REQUIRED` only where that verification is inapplicable |
| Duplicate component finding | Source retained; exactly one canonical ledger mapping |
### 5. Good/Base/Bad Cases
- Good: a historical P0 remains P0/confirmed while local remediation passes,
deployment is pending and external behavior is pending.
- Base: an open local-only QA finding uses `NO_FIX_TO_DEPLOY`,
`NOT_APPLICABLE` deployment or `NOT_REQUIRED` external verification as
appropriate.
- Bad: rename the discovery status to `RESOLVED` and omit whether the fix was
deployed or observed externally.
A confirmed historical P0 stays P0/confirmed after local remediation. Do not
replace discovery status with `RESOLVED` or a single `resolved` field that hides
deployment or observation.
### 6. Tests Required
- Task validation and Trellis governance.
- Sensitive-content scan and document registry audit.
- `git diff --check` plus a manual check that the recorded HEAD matches the
evidence-producing checkout.
Task validation, Trellis governance/sensitive scan, document registry audit and
`git diff --check`; verify that the recorded HEAD identifies the evidence-producing
checkout. Select additional checks from the changed contract.
### 7. Wrong vs Correct
#### Wrong
```json
{"findingId":"F-001","status":"resolved"}
```
`{"findingId":"F-001","status":"resolved"}` loses the discovery and verification states.
#### Correct
```json
{
"findingId": "F-001",
"discoverySeverity": "P0",
"discoveryStatus": "CONFIRMED",
"remediationStatus": "LOCAL_FIX_VERIFIED",
"deploymentStatus": "DEPLOYMENT_PENDING",
"externalVerificationStatus": "EXTERNAL_BEHAVIOR_PENDING"
}
```
Keep `discoverySeverity=P0`, `discoveryStatus=CONFIRMED`,
`remediationStatus=LOCAL_FIX_VERIFIED`, `deploymentStatus=DEPLOYMENT_PENDING`,
`externalVerificationStatus=EXTERNAL_BEHAVIOR_PENDING` when those facts apply.
## Scenario: QA Readiness Report Summaries
### 1. Scope / Trigger
- Trigger: QA shell runners aggregate child reports for launch, patrol,
smoke or readiness gates.
- Applies to generated `summary.json`, step JSON and privacy findings under
`artifacts/qa-flow/` or Trellis task research directories.
Shell runners aggregating child launch/patrol/smoke/readiness reports into
`summary.json`, step JSON or privacy findings under `artifacts/qa-flow/` or task research.
### 2. Signatures
- Parent shell runner writes `summary.json`.
- Child runner summary input: `<child-report-dir>/summary.json`.
- Step summary input/output: `<step-name>.step.json`.
Parent output: `summary.json`; child input: `<child-report-dir>/summary.json`;
step input/output: `<step-name>.step.json`.
### 3. Contracts
- Use repo-relative `reportRef` / `logRef` when a path is inside the repo.
- Do not write absolute local workspace paths into `summary.json`.
- Parent summaries must include child report status and child finding counts.
- Live-readiness summaries must distinguish the local `sourceCommit` from the
public `observedBuildSha`; a missing or mismatched public build marker cannot
produce a clean pass.
- Parent `findingCount` must become non-zero when any child summary reports
`PASS_WITH_FINDINGS`, `SKIP`, `PARTIAL`, `PAUSED`, `MISSING`, blocker-like
status or child `findingCount > 0`.
- Machine-readable reports may include status, count, mode, conclusion,
boolean operational flags and relative report refs.
- Machine-readable reports must not include amounts, prices, costs, balances,
bank details, invoice values, full accounts, tokens, secrets, raw payloads,
raw form values or full local paths.
- Credential/readiness presence reports must use safe business labels, not raw
env key names. For example, emit `adminCredentialReady: true` instead of a
field named after a credential-value environment variable.
- `check-pending-ocr.mjs` must reuse the adapter-backed Prisma client factory
and close both Prisma and its external PostgreSQL pool.
Use repo-relative `reportRef`/`logRef` for repository paths. Include each child's
status and finding count; any child finding or non-clean status makes parent
`findingCount` non-zero. Live readiness records local `sourceCommit` separately
from public `observedBuildSha`; absent/mismatched public identity cannot yield
a clean pass attributed to local HEAD.
Allow status/count/mode/conclusion, operational booleans and relative refs.
Exclude amounts/prices/costs/balances, bank/invoice details, full accounts,
tokens/secrets, raw payload/form values and absolute local paths. Presence
reports use safe labels such as `adminCredentialReady`, never secret-like raw
environment-key field names, even with boolean values.
`check-pending-ocr.mjs` reuses the adapter-backed Prisma client factory and
closes both Prisma and its external PostgreSQL pool.
### 4. Validation & Error Matrix
- Child `PASS` + `findingCount=0` -> parent may stay pass.
- Child `PASS_WITH_FINDINGS` -> parent records a finding.
- Child `SKIP` / `PARTIAL` / `PAUSED` / `MISSING` -> parent records
`manual_or_config`.
- Child `FAIL` / `BLOCKED` / `ERROR` -> parent records a finding or blocker
according to whether the parent step is required.
- Privacy smoke match -> write redacted finding metadata and make final
summary reflect the failure.
- Secret-like field names in generated reports -> privacy finding, even when
the value is only a boolean presence flag.
- Public `/ready` has no usable build SHA -> `manual_or_config` finding.
- Expected and observed public SHA differ -> `manual_or_config` finding or a
deployment blocker; never a clean pass attributed to local HEAD.
| Child/observation | Parent behavior |
| --- | --- |
| `PASS` and `findingCount=0` | May remain pass |
| `PASS_WITH_FINDINGS` or any child `findingCount>0` | Record a finding |
| `SKIP`, `PARTIAL`, `PAUSED`, `MISSING` | Record `manual_or_config` |
| `FAIL`, `BLOCKED`, `ERROR` or blocker-like status | Record finding/blocker according to whether the step is required |
| Privacy smoke match or secret-like report field | Redacted finding metadata; final summary reflects failure |
| Missing/unusable public `/ready` build SHA | `manual_or_config` finding |
| Expected/observed public SHA mismatch | `manual_or_config` or deployment blocker, never clean pass |
### 5. Good/Base/Bad Cases
- Good: `summary.json` contains `reportRef`, `childReports.<name>.status`,
`childReports.<name>.findingCount`, `sourceCommit`, `observedBuildSha` and no
absolute local path.
- Base: Missing runtime credentials produce `PASS_WITH_FINDINGS` or
`manual_or_config`, not a clean pass.
- Bad: Parent command exits 0 for a child `PASS_WITH_FINDINGS` and the parent
summary still says clean pass.
A parent report exposes child status/count and separate source/public identities.
Missing credentials produce `PASS_WITH_FINDINGS` or `manual_or_config`/blocking,
not clean readiness; exit 0 alone cannot erase a child's findings.
### 6. Tests Required
- `bash -n <runner>.sh`
- Run the parent runner in a missing-credential scenario and assert:
- parent status is `PASS_WITH_FINDINGS` or blocked, not clean pass;
- child finding count is visible in parent summary;
- privacy step is present in parent summary;
- `summary.json` has no full workspace path or business amount fields.
- For live/readiness env reports, assert the JSON contains safe readiness
labels and does not contain raw secret-like env key names.
- Run the matching launch/readiness aggregator when it consumes the report.
- Build a synthetic 40-character SHA and assert the public bundle contains only
its 12-character marker; use a local HTTP stub to assert readiness records and
matches the observed marker.
- `bash -n <runner>.sh`; exercise the parent/consuming aggregator with missing credentials. Assert parent `PASS_WITH_FINDINGS` or blocked, visible child count and privacy step, and absence of full paths/business amount fields.
- Assert safe readiness labels and no raw secret-like environment-key fields.
- Use a synthetic 40-character SHA to assert the public bundle exposes only its 12-character marker; a local HTTP stub verifies readiness reads and compares that marker.
### 7. Wrong vs Correct
#### Wrong
```json
{
"status": "PASS_OA_REAL_USE_DAILY_READY",
"reportDir": "/home/user/project/artifacts/qa-flow/run",
"childReports": {}
}
```
```json
{
"liveSmoke": {
"RAW_CREDENTIAL_ENV_KEY": true
}
}
```
A clean parent status with an empty `childReports` hides a child's findings;
a raw credential environment-key name remains unsuitable even with value `true`.
#### Correct
```json
{
"status": "PASS_WITH_FINDINGS",
"sourceCommit": "abcdef1234567890",
"observedBuildSha": "abcdef123456",
"buildShaMatches": true,
"reportRef": "artifacts/qa-flow/run",
"childReports": {
"oaOnlySmokeReadiness": {
"status": "PASS_WITH_FINDINGS",
"reportRef": "artifacts/qa-flow/run/oa-only-smoke-readiness/summary.json",
"findingCount": 7
}
}
}
```
```json
{
"liveSmoke": {
"adminCredentialReady": true
}
}
```
A `PASS_WITH_FINDINGS` summary records `sourceCommit`, `observedBuildSha`,
`buildShaMatches`, relative `reportRef`, and `childReports.<name>` with its
`status`, relative `reportRef` and `findingCount`. Credential presence uses
`liveSmoke.adminCredentialReady`, not a raw credential key.
+26 -16
查看文件
@@ -1,25 +1,35 @@
# hyb-oa Project Specs
These specs are the Trellis entry point for hyb-oa. They summarize stable
development rules and point back to the current Trellis task and `docs/`
fact sources.
Stable development contracts live here; current requirements and status live in
the Trellis task, while `docs/` remains the business fact source.
## Read Order
1. `project-governance.md`
2. The domain file matching the task.
3. The current `.trellis/tasks/<task>/prd.md` and `docs/文档索引.md`.
1. Start with the current PRD and latest implementation status. Resolve a stale/missing pointer with `task.py current --source`; inspect related tasks before creating one.
2. Reuse governance already loaded from AGENTS/workflow; consult `project-governance.md` for the relevant operation.
3. Select the affected domain below. Use `docs/文档索引.md` only to locate unresolved business facts.
## Domain Specs
| Spec | Purpose |
| Spec | Read when touching |
| --- | --- |
| `project-governance.md` | Official Trellis task contract, approvals, commit rules |
| `backend-fastify-prisma.md` | Server implementation and migration boundaries |
| `frontend-react-vite-design.md` | React/Vite UI and design-source rules |
| `approval-workflow.md` | OA approval/workflow/self-approval boundaries |
| `reimbursement-invoice-ocr.md` | Reimbursement, invoice, OCR and attachment rules |
| `wecom-boundary.md` | Enterprise WeChat ownership and API/write gates |
| `deployment-trialrun.md` | Public deployment, smoke, live-readiness and rollback gates |
| `docs-and-evidence.md` | Documentation reuse, evidence, Trellis task and status matrix |
| `security-privacy.md` | Privacy, secret handling and sensitive-data exclusions |
| `project-governance.md` | Task/approval rules; Trellis Project Upgrade Compatibility; Codex Inline Context Manifests |
| `backend-fastify-prisma.md` | Server APIs, transactions, migrations and data contracts |
| `frontend-react-vite-design.md` | React behavior, page permissions and design-source rules |
| `approval-workflow.md` | Approval states, self-approval and payment handoffs |
| `reimbursement-invoice-ocr.md` | Reimbursement, invoice, OCR and attachment handling |
| `wecom-boundary.md` | Enterprise WeChat ownership, APIs and write gates |
| `deployment-trialrun.md` | The specific candidate gate, deployment or recovery operation |
| `docs-and-evidence.md` | Evidence integrity, reporting and closeout |
| `security-privacy.md` | Authentication, sensitive-data access and privacy boundaries |
## Large Specs And Reusable Lessons
Locate sections with `rg -n '^#{1,3} ' .trellis/spec/hyb-oa/<file>.md`, then read
general rules, complete applicable scenarios and required references. Expand
for shared/cross-layer contracts; no search hit does not prove no rule applies.
Reuse unchanged sections already loaded instead of reading all domains.
For maintaining lessons and distinguishing evidence states, use
[Docs And Evidence rules](./docs-and-evidence.md#rules). A model upgrade does
not waive authorization, privacy, validation or independent review.
+9 -1
查看文件
@@ -29,6 +29,13 @@ tasks after TRELLIS2.
acceptance decisions require approval, not every intermediate action.
- Read the current phase and affected-layer contracts on demand. Reuse
unchanged context; do not require every document or thinking guide per turn.
- Resolve task identity with `task.py current --source` before broad session
dumps. A missing pointer does not authorize guessing another session's task
or creating a duplicate; inspect directly related task contracts.
- Use the package index and heading search for large specs, then read the
applicable general rules and complete scenarios. Do not treat a truncated
search excerpt as full contract coverage. Keep skills as small entry points,
with one owner for phase routing and reusable lessons.
- Prefer an available native plan tool. If unavailable, keep the checklist
in the current task implementation notes rather than stopping or creating
another planning system.
@@ -226,7 +233,8 @@ records the adopted scope and first reversible navigation reduction.
- Compile every Python file under `.trellis/scripts` and `.codex/hooks`.
- Exercise task validate/current/list and run Trellis governance.
- Archive the final active task and assert Trellis governance still passes with
zero active task directories.
zero active task directories in a disposable synthetic project only. This
runtime check does not authorize archiving a real task.
- Record pre-existing backup directory names before update; confirm no `.new`,
newly generated backup, bytecode or out-of-scope platform assets are tracked
or left for the sensitive scanner. Do not interpret a historical backup as