11 KiB
11 KiB
Project Governance
Main Rule
Trellis task directories are the execution contract for new hyb-oa work.
docs/ remains the business fact source. Historical issues/*.csv files remain
audit evidence and optional export material, but they are not mandatory for new
tasks after TRELLIS2.
Required Flow
- Start non-trivial work from a Trellis task with a PRD.
- Put goal, scope, out-of-scope, acceptance and test plan in
prd.md. - Add
design.mdorimplement.mdfor complex process, API, migration, permission, deployment or workflow-governance changes. - In sub-agent dispatch mode, curate
implement.jsonlandcheck.jsonlwith stable spec or research context only. In Codex inline mode they may contain no real entries because the main session reads specs directly. - Give a concrete implementation plan before coding and wait for approval.
- Keep edits scoped to the current Trellis task.
- Commit in Chinese and include the Trellis task name or task ID.
Solo Developer Operating Mode
hyb-oa is developed and maintained by one primary developer. Optimize every feature, improvement and refactor for low error rate, fast review, clear rollback and future self-maintenance.
- Prefer small, independently verifiable slices over broad rewrites.
- Before adding a new capability, ask whether it is high-frequency for a domestic tech startup with fewer than 10 people; low-frequency capability should be deferred, hidden behind advanced/admin entry, or kept as a manual procedure unless the current Trellis task explicitly approves it.
- Prefer existing modules, shared components, scripts and runbooks over new abstractions. Add platform-like infrastructure only when it removes real repeated work or reduces operational risk.
- Every task should state the minimum useful validation command set before implementation; do not rely on manual memory for gates.
- Keep rollout and rollback obvious. For public-facing changes, record the exact commit, deployment command, public check and whether the user can test.
- Capture reusable lessons in
docs/,.trellis/spec/or the current task while they are fresh; do not depend on chat history for project rules.
Stop Conditions
- Production config, deployment, database reset, migration drift, real data writes, Enterprise WeChat writes, payment actions, or destructive cleanup need explicit approval.
- Permission model, status machine, workflow engine, migration or approval-rule changes require read-only reviewer review after implementation.
Current Local Commands
python3 -m compileall -q .trellis/scripts .codex/hookspython3 ./.trellis/scripts/task.py validate <task>node scripts/qa/check-trellis-governance.mjsgit diff --checkbash scripts/check-minimal.sh
Scenario: Trellis Project Upgrade Compatibility
1. Scope / Trigger
- Trigger: upgrading the project Trellis version, applying migrations, or refreshing managed platform assets.
- Purpose: prevent a template update from silently breaking the project's actual Python runtime or enabling an AI platform that is not in scope.
2. Signatures
- Version check:
trellis --versionand.trellis/.version. - Runtime check:
python3 -m compileall -q .trellis/scripts .codex/hooks. - Project preview:
trellis update --dry-runusing the target CLI version. - Task smoke tests:
task.py validate,task.py current --source --jsonandtask.py list --json.
3. Contracts
- Run compile checks with the same
python3executable used by project Trellis commands; compatibility with a newer developer interpreter is not sufficient. - Project-enabled platforms are authoritative. A local-only settings directory
such as
.claude/must not cause an out-of-scope managed platform bundle to enter the upgrade diff. - Temporarily isolating a local-only platform directory is allowed only when its exact contents are restored after update and the final diff confirms no managed assets for that platform were added.
- Preserve intentional local overlays through explicit merge; do not use
--forceto eraseworkflow.md,config.yaml,.gitignoreorAGENTS.md. - Treat dry-run output and manifest cleanliness as evidence, but do not assume
a dry-run is write-free; inspect
git statusbefore and after it.
4. Validation & Error Matrix
- Runtime compile failure -> stop the upgrade and fix or revert the incompatible managed script before running task commands.
- Unexpected platform assets in dry-run or final diff -> stop, correct platform discovery, and rerun the preview.
.newconflict files remain -> upgrade is incomplete; merge or discard each one deliberately.- Post-upgrade dry-run changes manifest again -> investigate template hash drift before commit.
- Only documented project overlays remain modified -> acceptable after task and governance gates pass.
5. Good/Base/Bad Cases
- Good: isolate a local-only
.claude/, update Codex assets, restore the local setting, compile with project Python, then verify a stable dry-run. - Base: update a project with no local platform ambiguity and run the same compile, task and governance checks.
- Bad: accept generated Claude assets because
.claude/settings.local.jsonhappened to exist, or validate Python code only with a newer interpreter.
6. Tests Required
- Assert CLI and project versions match the intended target.
- Compile every Python file under
.trellis/scriptsand.codex/hooks. - Exercise task validate/current/list and run Trellis governance.
- Confirm no
.new, backup, bytecode or out-of-scope platform assets are tracked; finish withgit diff --check.
7. Wrong vs Correct
Wrong
trellis update reports success -> commit immediately
Correct
preview platform scope -> conservative update/migrate -> merge overlays
-> compile with project Python -> smoke-test task runtime -> stable dry-run
-> governance and project gates -> commit
Legacy Issue CSV
- Do not delete, bulk rewrite or move historical
issues/*.csvfiles. - New work may mention an old Issue CSV for traceability, but must not require a new CSV unless the user explicitly requests legacy/export evidence.
Scenario: Interrupted Or Superseded Task Closeout
1. Scope / Trigger
- Trigger: a Trellis task is interrupted, expired, cancelled or superseded and should leave the active-task list even though its original goal was not met.
- Purpose: keep lifecycle state clean without turning archival metadata into a false claim that acceptance criteria or business outcomes were completed.
2. Signatures
- Command:
python3 ./.trellis/scripts/task.py archive <task-name>. - Effects: moves the task under
.trellis/tasks/archive/<year-month>/, writestask.json.status=completedand setscompletedAt.
3. Contracts
- For interrupted or superseded tasks,
status=completedmeans lifecycle closed; it does not mean the original goal or every acceptance criterion was achieved. - Before archive, add a
Lifecycle Closeoutsection toprd.mdand a concisetask.json.notessummary covering: what was actually completed, what is missing, why the task stopped and which future task or condition replaces it. - Leave unmet acceptance checkboxes unchecked. Never create missing dates, tests, human confirmation or production evidence merely to make the archived task look complete.
- Current indexes or runbooks must use the same closeout semantics when the task previously represented an active operational fact.
4. Validation & Error Matrix
- All acceptance criteria achieved with evidence -> normal completed archive.
- Goal incomplete but closeout section and notes are explicit -> lifecycle archive is allowed; downstream readers must not infer goal completion.
- Goal incomplete and closeout evidence is absent -> do not archive yet.
- Historical evidence missing -> record it as missing; do not reconstruct or backdate evidence.
5. Good/Base/Bad Cases
- Good: a seven-day trial with only Day 1-Day 4 records is archived with the missing days, absent human closure and successor trial stated explicitly.
- Base: a fully verified implementation is archived with its implementation and deployment commits referenced.
- Bad: mark Day 5-Day 7 complete or check all PRD boxes only because the task is old and should disappear from the active list.
6. Tests Required
python3 ./.trellis/scripts/task.py validate <task-or-archive-path>.- Inspect archived
task.jsonforstatus,completedAtand truthfulnotes. - Run
node scripts/qa/check-trellis-governance.mjsandgit diff --check. - When the task affects current operational truth, run the documentation audit and verify index/runbook wording matches the closeout outcome.
7. Wrong vs Correct
Wrong
{ "status": "completed", "notes": "7 天试运行完成" }
Correct
{
"status": "completed",
"notes": "生命周期关闭:仅完成 Day 1-Day 4,原目标未完成;未来由新任务从 Day 1 替代。"
}
Scenario: Codex Inline Context Manifests
1. Scope / Trigger
- Trigger: creating, validating or finishing a Trellis task while
.trellis/config.yamlsetscodex.dispatch_mode: inline.
2. Signatures
- Config:
codex.dispatch_mode: inline | sub-agent. - Context files:
<task>/implement.jsonl,<task>/check.jsonl. - Gates:
node scripts/qa/check-trellis-governance.mjsandpython3 ./.trellis/scripts/task.py validate <task>.
3. Contracts
- Inline mode may keep both JSONL files at zero real entries; the seed
_examplerow does not count as injected context. - If an inline task contains real entries, each entry must still be valid JSON
with non-empty
fileandreason; normal path and context warnings apply. - Sub-agent mode requires at least one real entry in each manifest.
- Switching dispatch mode changes the validation policy, not historical task evidence and not the requirement to read specs before implementation.
4. Validation & Error Matrix
- Inline + zero real entries -> pass with
*_inline_optional. - Inline + malformed real entry -> fail.
- Sub-agent + zero real entries -> fail with
*_empty. - Either mode + non-spec/non-research context -> warning for review.
5. Good/Base/Bad Cases
- Good: inline task uses the seed-only files and the main agent reads specs.
- Base: inline task keeps curated entries for audit; they remain validated.
- Bad: governance fabricates placeholder entries only to satisfy a rule meant for sub-agent context injection.
6. Tests Required
- Fixture test for inline seed-only pass.
- Fixture test for sub-agent seed-only failure.
- Run both Trellis governance and
task.py validatefor the active task.
7. Wrong vs Correct
Wrong
dispatch_mode=inline -> require at least one injected JSONL entry
Correct
dispatch_mode=inline -> allow zero real entries; validate any real entries
dispatch_mode=sub-agent -> require curated real entries