Skip to content

Commit c5f4130

Browse files
committed
feat: make env-lock/eval-executor/consensus stubs real; ADR-0041 Phase-1 budget clamp
Replaces disclosed stubs with real, tested implementations and lands the first behavior-preserving slice of the execution-surface unification. Execution-surface unification (ADR-0041 Phase 1; extends ADR-0040 / A-P1-3): - New docs/adr/0041: phased plan to define governed execution once and thin the harness; status Proposed, gates G1-G5 still unmet (only G2-budget advanced). - Budget clamp single-sourced: subagents/_manager._resolve_budget_limits now delegates to runner/_invariants.compute_clamped_budget (was a hand-kept mirror). env lock (installed-snapshot semantics): - env_config.generate_lockfile resolves declared packages against the installed environment via importlib.metadata (version + sha256 over RECORD hashes; missing package raises EnvLockResolutionError). env_manager.verify recomputes + compares. - env lock subcommand un-hidden in the CLI. eval executor: - EvalRunner gains a real model_runner seam feeding the existing scorer; release gate derives simulated/advisory flags from per-test execution mode. No-runner path unchanged (disclosed advisory). consensus (real + un-hidden): - consensus history reads stored states; consensus config set persists config. TUI cockpit: - _refresh_cockpit_state populates budget + recoverable so the Run-status panel renders Budget/Undo/Checkpoint/Suspended lines. Hardening + docs: - SEC-11 undo shell-mutation warning; risk register SEC-12 marked fixed. - Roadmap / ticket-index / inline-todos drift corrected; new doc-code-reference and inline-todo-catalog validators in scripts/validate_docs_consistency.py. Action: A-P1-3 Constraint: behavior-preserving and offline-only (no network resolver, no live model); the high-risk execution-surface change is limited to one identical-math clamp delegation; prerequisite-blocked items (network-resolved lock, live-model eval signal) left honest/failing-loud rather than faked Tested: ruff check + ruff format --check clean; mypy clean on touched modules; 120 affected tests pass (env/eval/release-gate/runner-invariants + subagent budget-inheritance integration); validate_docs_consistency.py exit 0; validate_runner_invariants.py exit 0; CLI smokes (env lock/verify/tamper, env --help shows lock, eval gate real vs advisory) Not-tested: full repo suite not run by me (pre-commit runs the smoke subset + full mypy); live-model eval signal and network-resolved lock intentionally not implemented Confidence: high
1 parent 357449e commit c5f4130

44 files changed

Lines changed: 2017 additions & 188 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/INDEX.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ Use this short list instead of scanning every dated analysis file.
117117

118118
| Plan | Use it for |
119119
| --- | --- |
120-
| [Work Direction Decomposition](plans/work-direction-decomposition-2026-06-10.md) | Full WD-A … WD-H backlog with acceptance gates. |
120+
| [Work Direction Decomposition](plans/work-direction-decomposition-2026-06-10.md) | WD-A … WD-H backlog with acceptance gates; **execution closed except WDH-002 partial** — see [Work Direction Execution Index](plans/work-direction-execution-index-2026-06-10.md) for current closure status. |
121121
| [Documentation Optimization Master Plan](plans/documentation-optimization-master-plan-2026-06-04.md) | Prioritizing documentation work by stability, UX, risk, and ROI. |
122122
| [Documentation Optimization Work Items](work-log/documentation-optimization-work-items-2026-06-04.md) | Concrete task execution ledger. |
123123
| [Daily-Driver Complete Work Plan](plans/daily-driver-complete-work-plan-risk-roi-2026-06-04.md) | Historical daily-driver risk, feasibility, ROI, and sequence; use harness-first direction for current persona claims. |

docs/adr/0041-execution-surface-unification-and-harness-thinning.md

Lines changed: 322 additions & 0 deletions
Large diffs are not rendered by default.

docs/adr/README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
[README.md#A828]
12
# Architecture Decision Records (ADR)
23

34
This directory contains all Architecture Decision Records (ADRs) for the TeaAgent project. ADRs document significant architectural decisions, their rationale, and consequences.
@@ -35,6 +36,7 @@ This directory contains all Architecture Decision Records (ADRs) for the TeaAgen
3536
| 0031 | Shadow Mode Exit Criteria | Proposed | 2026-06-12 | 2026-09-12 (expiry review) |
3637
| 0032 | Run Event Taxonomy and Event Spine | Accepted and Implemented | 2026-06-13 | 2026-06-17 |
3738
| 0040 | Reconcile the Second Execution Framework with the Primary Runner | Accepted | 2026-06-20 | - |
39+
| 0041 | Execution Surface Unification and Harness Thinning | Proposed | 2026-06-30 | - |
3840

3941
## ADR Categories
4042

@@ -50,6 +52,10 @@ This directory contains all Architecture Decision Records (ADRs) for the TeaAgen
5052
- **0007**: ANP Adapter Boundary - External federation boundary
5153
- **0008**: P4 Strategic Posture - Storage, TLS, P2P auth posture
5254

55+
### Execution Architecture (0040-0041)
56+
- **0040**: Reconcile the Second Execution Framework with the Primary Runner - Shared-invariant contract and CI gates
57+
- **0041**: Execution Surface Unification and Harness Thinning - Shared governed-execution layer; domain migration to skills/model
58+
5359
### Governance Hardening (0009, 0022-0024, 0029, 0031-0032)
5460
- **0009**: 5-Loop Governance System - Comprehensive governance loops
5561
- **0022**: Centralized Approval Queue for Subagents - Batch approval management
@@ -81,7 +87,7 @@ This directory contains all Architecture Decision Records (ADRs) for the TeaAgen
8187
- **Accepted and Implemented**: Decision accepted and fully implemented
8288
- **Accepted and Implemented (Beta)**: Decision accepted and implemented in Beta (optional hardening remaining)
8389
- **Superseded / Archived / Rejected**: Closed decisions with details in respective files
84-
- ~~**Proposed**~~: No ADRs are currently in Proposed state (all refactoring proposals were resolved June 2026; see DOCOPT-010).
90+
- **Proposed**: Decision recorded; implementation not yet started or incomplete (see ADR-0031, ADR-0041).
8591

8692
## Git History
8793

docs/backlog-priority.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Backlog Priority
22

3-
> **Last reviewed:** 2026-06-06
3+
> **Last reviewed:** 2026-06-28
44
> **Review trigger:** Backlog priorities or shipped/beta status claims change.
55
> **Scheduling gate (2026-06-22):** DR-001 met — 5 owner evidence entries in
66
> [Operator Friction Log](work-log/operator-friction-log.md). New UX work should cite
@@ -30,14 +30,14 @@ DR-001 (owner friction evidence) completes.
3030
| --- | --- | --- |
3131
| CP-4 OpenCode Gap Watch | `legacy-competitive` | Monitoring only; escalation → feature sprint **blocked** without friction evidence |
3232
| CP-6 Community Presence | `legacy-competitive` | **Hold** — external acquisition non-goal |
33-
| M4 cloud/background/control-plane cockpit | `legacy-competitive` | **Hold** — T4 owner decision |
33+
| M4 cloud/background/control-plane cockpit | `legacy-competitive` | **Hold except DR-006 carve-out**background lifecycle + operator cockpit may proceed under owner-override co-maintainer dogfood; cloud/SaaS/multi-tenant GTM held (T4 owner decision) |
3434
| RBAC enforce flip (ADR 0031, 2026-09-12) | `governance-gap` | **Hold** until owner demand signal |
3535
| TASK-006 RunEvent taxonomy + M0 | `harness-migration` | **Promote** |
3636
| TASK-001 constitution repositioning | `owner-override` | **Promote** (harness-first ratified) |
3737
| TASK-002 docs tiering | `harness-migration` | **Promote** |
3838
| TASK-003 test typing pass | `harness-migration` | **Promote** |
3939
| TASK-004 flagship tests off deprecated approval | `governance-gap` | **Promote** |
40-
| TASK-007 friction log bootstrap | `friction-driven` | **Owner-blocking**0/5 evidence entries |
40+
| TASK-007 friction log bootstrap | `friction-driven` | **Met (2026-06-22)**5/5 owner evidence entries (F2/F3/F6/F7/F8); DR-001 7b satisfied |
4141
| Phase 4–6 Beta (consensus, sandbox, control plane) | `owner-override` | Shipped; **freeze** new platform surface per T3/T4 |
4242
| Competitive refresh release gate | `legacy-competitive` | **Resolved (DR-006 T5):** split gate — CI blocks on `main`; manual survey quarterly |
4343
| Seven-control-loops SCL-P0 tickets | `legacy-competitive` | **Hold** until owner validates in friction log |

docs/generated/docs-aging-dashboard.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
**Stale threshold:** 90 days since `Last reviewed`
66
**Current-truth docs scanned:** 17
7-
**Needs attention (working tier only):** 11
7+
**Needs attention (working tier only):** 12
88
**Archive-tier docs (exempt from staleness):** 0
99

1010
Regenerate: `python3 scripts/report_docs_aging.py`
@@ -28,13 +28,14 @@ Regenerate: `python3 scripts/report_docs_aging.py`
2828
| Document | Status | Last reviewed | File mtime | Notes |
2929
| --- | --- | --- | --- | --- |
3030
| `docs/daily-driver-current-status.md` | stale_by_mtime | 2026-06-25 | 2026-06-26 | File modified after last reviewed date |
31+
| `docs/plans/ticket-plans/index.md` | stale_by_mtime | 2026-06-18 | 2026-06-30 | File modified after last reviewed date |
3132
| `docs/USAGE.md` | stale_by_mtime | 2026-06-06 | 2026-06-21 | Missing owner banner; File modified after last reviewed date |
3233

3334
### docs
3435

3536
| Document | Status | Last reviewed | File mtime | Notes |
3637
| --- | --- | --- | --- | --- |
37-
| `docs/INDEX.md` | stale_by_mtime | 2026-06-17 | 2026-06-22 | Missing owner banner; File modified after last reviewed date |
38+
| `docs/INDEX.md` | stale_by_mtime | 2026-06-17 | 2026-06-28 | Missing owner banner; File modified after last reviewed date |
3839

3940
### governance
4041

@@ -55,11 +56,11 @@ Regenerate: `python3 scripts/report_docs_aging.py`
5556
| --- | --- | --- | --- | --- |
5657
| `docs/release-checklist.md` | stale_by_mtime | 2026-06-07 | 2026-06-22 | Missing owner banner; File modified after last reviewed date |
5758

58-
### strategy
59+
### roadmap
5960

6061
| Document | Status | Last reviewed | File mtime | Notes |
6162
| --- | --- | --- | --- | --- |
62-
| `docs/backlog-priority.md` | stale_by_mtime | 2026-06-06 | 2026-06-22 | Missing owner banner; File modified after last reviewed date |
63+
| `docs/roadmap-status.md` | stale_by_mtime | 2026-06-28 | 2026-06-30 | File modified after last reviewed date |
6364

6465
### verification
6566

docs/generated/docs-inventory.md

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
Generated by `python3 scripts/generate_docs_inventory.py`.
77
Do not edit this file manually — regenerate instead.
88

9-
**Markdown files:** 610
9+
**Markdown files:** 611
1010

1111
| Path | Tier | Bytes | SHA256 (12) |
1212
| --- | --- | ---: | --- |
@@ -44,7 +44,8 @@ Do not edit this file manually — regenerate instead.
4444
| `adr/0031-shadow-mode-exit-criteria.md` | working | 3598 | `46a9a0d5eaac` |
4545
| `adr/0032-run-event-taxonomy.md` | working | 16065 | `b9f0c0d7c30a` |
4646
| `adr/0040-second-framework-invariants.md` | working | 7554 | `00b53102ace3` |
47-
| `adr/README.md` | working | 7238 | `ab51ac7bdf24` |
47+
| `adr/0041-execution-surface-unification-and-harness-thinning.md` | working | 16521 | `a4b8d6092d63` |
48+
| `adr/README.md` | working | 7611 | `c91dd1b63df7` |
4849
| `agent-contribution-contract.md` | constitution | 5204 | `9c2dad1195d2` |
4950
| `agent-mode-operator-guide.md` | working | 2778 | `25b258ab7bfe` |
5051
| `analysis/active-findings-status-ledger-2026-06-06.md` | working | 5261 | `a567ee017c86` |
@@ -188,7 +189,7 @@ Do not edit this file manually — regenerate instead.
188189
| `architecture/seven-control-loops-teaagent-integration-map-2026-06-05.md` | archive | 9282 | `6d85e832f8eb` |
189190
| `archive/INDEX.md` | working | 8774 | `1efa1af575f5` |
190191
| `audit-events.md` | working | 2376 | `b83066076fba` |
191-
| `backlog-priority.md` | working | 32137 | `6260226b3d50` |
192+
| `backlog-priority.md` | working | 32338 | `4fcd06c4782f` |
192193
| `cli.md` | working | 36528 | `88e79b022406` |
193194
| `cloud-deployment.md` | working | 9431 | `50f6461a2077` |
194195
| `context-bus-and-federated-sync.md` | working | 1564 | `2dde6eed4bf8` |
@@ -236,7 +237,7 @@ Do not edit this file manually — regenerate instead.
236237
| `error-reference.md` | working | 4897 | `067448aba6f1` |
237238
| `gateway-oauth-tenants.md` | working | 1818 | `0ff9c7df4652` |
238239
| `generated/command-snippet-inventory.md` | working | 8128 | `f11e933dfa4d` |
239-
| `generated/docs-aging-dashboard.md` | working | 4776 | `892d94253bf9` |
240+
| `generated/docs-aging-dashboard.md` | working | 4874 | `e67eb57e9200` |
240241
| `generated/release-docs-evidence.md` | working | 2517 | `e28e92734209` |
241242
| `governance-compliance.md` | constitution | 1645 | `d7665f2f7864` |
242243
| `governance/code-review-checklist.md` | working | 4379 | `f580da208c75` |
@@ -294,7 +295,7 @@ Do not edit this file manually — regenerate instead.
294295
| `http-surface-auth.md` | working | 5135 | `e5299e595353` |
295296
| `implementation/daily-driver-fix-log.md` | working | 978 | `474648b41793` |
296297
| `implementation/fix-log-2026-06-02.md` | archive | 8520 | `21239812e63e` |
297-
| `INDEX.md` | working | 16130 | `265f5e86325d` |
298+
| `INDEX.md` | working | 16290 | `68f1d06bf1c0` |
298299
| `maturity-matrix.md` | working | 6953 | `b5616937c67a` |
299300
| `migration-top-level-api.md` | working | 1505 | `2ba32dedee5a` |
300301
| `model-capability-matrix.md` | working | 4662 | `86fcdd45e9ab` |
@@ -456,8 +457,8 @@ Do not edit this file manually — regenerate instead.
456457
| `plans/system-improvement-work-directions-2026-06-06.md` | archive | 11080 | `a9ec8e82af9a` |
457458
| `plans/system-review-workstream-traceability-2026-06-06.md` | archive | 10935 | `8e077ba5b22c` |
458459
| `plans/system-transparency-engineering-plan-2026-05-31.md` | archive | 15162 | `7bf5da7ec519` |
459-
| `plans/ticket-plans/index.md` | working | 9875 | `634b2a3a9540` |
460-
| `plans/ticket-plans/inline-todos.md` | working | 3174 | `cf4a1ad4ebdf` |
460+
| `plans/ticket-plans/index.md` | working | 10063 | `20fe11338f82` |
461+
| `plans/ticket-plans/inline-todos.md` | working | 4869 | `42d9ddc85724` |
461462
| `plans/ticket-plans/TASK-DD2-001-plan.md` | working | 5066 | `1ed3777aca5e` |
462463
| `plans/ticket-plans/TASK-DD2-002-plan.md` | working | 4473 | `98f157e4cd07` |
463464
| `plans/ticket-plans/TASK-DD2-003-plan.md` | working | 1665 | `1914b55b8fd9` |
@@ -536,7 +537,7 @@ Do not edit this file manually — regenerate instead.
536537
| `reviews/runner-tool-decision-split-risk.md` | working | 2978 | `597a932c0ae6` |
537538
| `reviews/security-risk-assessment-2026-06-02.md` | archive | 24112 | `4c9e2e00d001` |
538539
| `reviews/seven-control-loops-critical-questioning-2026-06-05.md` | archive | 7531 | `ae1e34b8369d` |
539-
| `roadmap-status.md` | constitution | 20910 | `17a4c5db9445` |
540+
| `roadmap-status.md` | constitution | 21221 | `a5134cce3523` |
540541
| `run-evidence-and-audit-guide.md` | working | 2158 | `9c369d008852` |
541542
| `security-whitepaper.md` | working | 9690 | `87fc3c31c4a3` |
542543
| `security/approval-abuse-cases-2026-06-02.md` | archive | 1281 | `4c43296d1c66` |
@@ -547,7 +548,7 @@ Do not edit this file manually — regenerate instead.
547548
| `security/path-and-root-threat-scenarios-2026-06-02.md` | archive | 1270 | `bb44fc81a366` |
548549
| `security/phase-0-trust-repair-risk-brief-2026-06-04.md` | archive | 5801 | `b123bdc43b26` |
549550
| `security/rate-limiting.md` | working | 2409 | `dfb2d06f42b2` |
550-
| `security/risk-register-and-threat-model-2026-06-02.md` | archive | 59369 | `889284fbc443` |
551+
| `security/risk-register-and-threat-model-2026-06-02.md` | archive | 60953 | `f066a289b17f` |
551552
| `security/severity-calibration-rubric.md` | working | 2828 | `8af4af679012` |
552553
| `security/shell-safety.md` | working | 7163 | `7885c6a889dc` |
553554
| `skill-governance.md` | working | 12561 | `44967dfcc037` |
@@ -580,8 +581,8 @@ Do not edit this file manually — regenerate instead.
580581
| `strategy/agent-ecosystem-core-values-2026-06-05.md` | archive | 12861 | `23194f9dc611` |
581582
| `strategy/competitive-analysis-and-positioning-2026-06-06.md` | archive | 67553 | `7c78b145750a` |
582583
| `strategy/daily-driver-roadmap-rationale-2026-06-04.md` | archive | 5053 | `3b6cdeed6d2e` |
583-
| `strategy/direction-review-agenda-2026-06-22.md` | archive | 10799 | `790b5c1c564e` |
584-
| `strategy/dr-006-owner-decision-2026-06-22.md` | archive | 3838 | `13d04d3f155e` |
584+
| `strategy/direction-review-agenda-2026-06-22.md` | archive | 10676 | `8fd32792147f` |
585+
| `strategy/dr-006-owner-decision-2026-06-22.md` | archive | 3892 | `7f90e1c47e7d` |
585586
| `strategy/harness-first-direction-2026-06-13.md` | constitution | 21061 | `7879fb8c6994` |
586587
| `strategy/implementation-roadmap-with-effort-impact-2026-06-06.md` | archive | 58270 | `fb0af11ee7a6` |
587588
| `strategy/malleable-governed-agent-harness-2026-06-03.md` | archive | 15446 | `eccbc0177490` |

docs/plans/ticket-plans/index.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,7 @@ only the daily-driver fixes:
105105
See [inline-todos.md](inline-todos.md) for the full catalog of `# TODO`,
106106
`# FIXME`, and implicit architectural TODOs across the codebase.
107107

108-
**TL;DR:** 1 production `TODO` (`issue_intake.py:195` — GitHub API stub), 9 in
109-
monitoring scripts, 7 implicit architectural items (all ticketed above).
108+
**Current TL;DR:** See [inline-todos.md](inline-todos.md) for the current explicit-marker counts (guarded against source drift by `validate_inline_todo_catalog` in `scripts/validate_docs_consistency.py`) and the list of implicit deferrals awaiting owner/ticket review. This index no longer restates the counts so it cannot drift out of sync.
110109

111110
---
112111

docs/plans/ticket-plans/inline-todos.md

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
# Inline TODO / FIXME / XXX Catalog
2-
**Generated:** 2026-06-02 | **Last reviewed:** 2026-06-09 | **Scope:** `teaagent/` and `scripts/`
2+
**Generated:** 2026-06-02 | **Last reviewed:** 2026-06-30 | **Scope:** `teaagent/` and `scripts/`
33

44
---
55

66
## Production source (`teaagent/`)
77

88
| File | Line | Comment | Context | Action |
99
|------|------|---------|---------|--------|
10-
| [`teaagent/issue_intake.py`](../../../teaagent/issue_intake.py) | 195 | GitHub API integration | **Fixed (2026-06-09):** `extract_github_issue()` uses PyGithub with `GITHUB_TOKEN`; raises actionable errors when library/token missing. | None — closed. |
10+
| [`teaagent/domain/issue_intake.py`](../../../teaagent/domain/issue_intake.py) | 194 | GitHub API integration | **Fixed (2026-06-09):** `extract_github_issue()` uses PyGithub with `GITHUB_TOKEN`; raises actionable errors when library/token missing. | None — closed. |
11+
| [`teaagent/tui/cockpit_data_sources.py`](../../../teaagent/tui/cockpit_data_sources.py) | 158 | Cost period attribution | **Fixed (2026-06-30):** `CostDataSource.get_costs()` now derives `CostRow.period` from `RunSummary.updated_at` with an `unknown` fallback. | None — closed. |
1112

1213
---
1314

@@ -23,14 +24,27 @@ are stubs left from scaffolding and are lower priority.
2324

2425
---
2526

26-
## Architectural dead-letter items
27+
## Implicit deferrals requiring owner / ticket
28+
29+
These are not literal `# TODO` comments, so the explicit TODO drift guard does
30+
not count them. They remain review-needed until each is either ticketed,
31+
implemented, or explicitly documented as intentional scaffolding.
32+
33+
| Location | Pattern | Action |
34+
|----------|---------|--------|
35+
| `teaagent/consensus/consensus_validation.py:113-114` | Voter role is inferred from `voter_id` instead of looked up. | Ticket consensus role source of truth or document why `voter_id` encoding is contractual. |
36+
| `teaagent/domain/workflow_engine.py:357-358` | Workflow step execution is simulated. | Ticket real agent invocation boundary before treating workflow engine as production execution. |
37+
| `teaagent/eval_suite.py:410-517` | Eval execution and baseline diffing use placeholder/simulated behavior. | Ticket real executor/diff semantics or label suite as non-gating simulation. |
38+
| `teaagent/cli/_handlers/_consensus.py:154,177` | Consensus history query and configuration persistence are not implemented. | Ticket persistence/history or hide commands from production-facing flows. |
39+
| `teaagent/domain/agent_factory.py:434-435` | Agent removal is logged as not fully implemented. | Ticket registry removal support and persisted cleanup semantics. |
40+
| `teaagent/domain/issue_intake.py:570,776` | Plan exploration and generated command are placeholders. | Ticket PlanMode integration or label issue-intake plan execution as advisory only. |
2741

28-
These are not inline comments but recurring patterns the audit uncovered that
29-
function as implicit TODOs:
42+
---
43+
44+
## Architectural dead-letter items
3045

31-
**2026-06-04 update:** Several entries in the original generated catalog are
32-
now fixed. They are kept below with status so the historical audit remains
33-
traceable without re-opening closed work.
46+
These are historical implicit TODOs. They are kept below with status so the
47+
audit remains traceable without re-opening closed work.
3448

3549
| Location | Pattern | Status / Implicit TODO |
3650
|----------|---------|------------------------|
@@ -50,6 +64,7 @@ traceable without re-opening closed work.
5064
|----------|-------|
5165
| Explicit `# TODO` in production (`teaagent/`) | 0 |
5266
| Explicit `# TODO` in scripts (unfixed stubs) | 0 |
67+
| Implicit deferrals requiring owner / ticket | 6 review-needed |
5368
| Implicit architectural TODOs (ticketed) | 0 active |
54-
| **Active total** | **0** |
55-
| Fixed historical entries retained | 9 |
69+
| **Active total** | **6 review-needed** |
70+
| Fixed historical entries retained | 11 |

0 commit comments

Comments
 (0)