升级Trellis并精简项目知识(09-05-trellis-upgrade-rule-cleanup)
更新Trellis适配、任务归属与归档失败恢复,精简技能入口和知识读取规则。 保留权限、证据、事务及独立复核合同;纳入对应任务及已完成复核记录。 仅本地提交,不启用新平台适配,不推送或部署。
这个提交包含在:
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
在新工单中引用
屏蔽一个用户