1_general_forum/currency-ledger/scripts/task-management/assess-work-session.py

251 lines
10 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""
Assess work session effort and recommend SC payout
Converts human collaboration into fair compensation through structured evaluation
Version: 0.1 (Prototype for 6_0_3_0)
"""
import argparse
import csv
import yaml
from datetime import datetime
from pathlib import Path
class SessionAssessor:
def __init__(self):
# Fix: Need to go up 3 levels from scripts/task-management/ to currency-ledger/
self.base_path = Path(__file__).parent.parent.parent
self.policies_path = self.base_path / "policies" / "task-management"
self.ledger_path = self.base_path / "ledger"
print(f"Debug: Base path = {self.base_path}")
print(f"Debug: Policies path = {self.policies_path}")
def load_assessment_template(self):
"""Load effort assessment scoring criteria"""
template_file = self.policies_path / "effort-assessment-template.yml"
print(f"Debug: Looking for template at {template_file}")
with open(template_file, 'r') as f:
return yaml.safe_load(f)
def get_task_data(self, task_id):
"""Retrieve task budget information"""
budget_file = self.ledger_path / "task-management" / "task-budgets.csv"
with open(budget_file, 'r') as f:
reader = csv.DictReader(f)
for row in reader:
if row['task_id'] == task_id:
return row
raise ValueError(f"Task {task_id} not found in task budgets")
def calculate_payout_percentage(self, attacker_score, defender_score, collaboration_score, template):
"""Calculate SC payout percentage based on effort scores"""
total_score = attacker_score + defender_score + collaboration_score
max_score = 30 # 3 categories × 10 points each
# Use template scoring ranges
payout_ranges = template['payout_calculation']
if total_score >= 27: # 90%+ of max
return 95 # excellent_session range
elif total_score >= 24: # 80%+ of max
return 85 # good_session range
elif total_score >= 18: # 60%+ of max
return 70 # adequate_session range
elif total_score >= 6: # 20%+ of max
return 40 # poor_session range
else:
return 10 # failed_session range
def create_session_log(self, session_data):
"""Log session details for transparency"""
session_file = self.ledger_path / "task-management" / "session-logs.csv"
# Create header if file doesn't exist
if not session_file.exists():
with open(session_file, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow([
'session_id', 'task_id', 'start_time', 'end_time',
'attacker', 'defender', 'mission_leader',
'attacker_effort_score', 'defender_learning_score', 'collaboration_score',
'total_score', 'recommended_payout_percent', 'session_notes'
])
# Add session record
with open(session_file, 'a', newline='') as f:
writer = csv.writer(f)
writer.writerow([
session_data['session_id'],
session_data['task_id'],
session_data['start_time'],
session_data['end_time'],
session_data['attacker'],
session_data['defender'],
session_data['mission_leader'],
session_data['attacker_effort_score'],
session_data['defender_learning_score'],
session_data['collaboration_score'],
session_data['total_score'],
session_data['recommended_payout_percent'],
session_data['session_notes']
])
def create_pending_sc_entries(self, task_data, session_data):
"""Create entries in pending-sc for democratic validation"""
pending_file = self.ledger_path / "pending-sc" / "transactions.csv"
# Calculate actual SC amounts
payout_percent = session_data['recommended_payout_percent'] / 100
attacker_sc = int(int(task_data['attacker_sc']) * payout_percent)
defender_sc = int(int(task_data['defender_sc']) * payout_percent)
# Create pending SC entries (integrate with existing system)
entries = [
{
'timestamp': datetime.now().isoformat(),
'type': 'PENDING_SC',
'amount': attacker_sc,
'from': '',
'to': task_data['attacker_alias'],
'reference': f"task-{task_data['task_id']}-attacker",
'description': f"Task {task_data['task_id']}: {task_data['title']} - Attacker role ({session_data['recommended_payout_percent']}% effort payout)",
'validator_required': 'team-captain',
'phase': 'validation',
'evidence_link': task_data['forgejo_issue_url'],
'status': 'PENDING_VALIDATION',
'vesting_tranche': ''
},
{
'timestamp': datetime.now().isoformat(),
'type': 'PENDING_SC',
'amount': defender_sc,
'from': '',
'to': task_data['defender_alias'],
'reference': f"task-{task_data['task_id']}-defender",
'description': f"Task {task_data['task_id']}: {task_data['title']} - Defender role ({session_data['recommended_payout_percent']}% effort payout)",
'validator_required': 'team-captain',
'phase': 'validation',
'evidence_link': task_data['forgejo_issue_url'],
'status': 'PENDING_VALIDATION',
'vesting_tranche': ''
}
]
# Append to existing pending-sc file
with open(pending_file, 'a', newline='') as f:
writer = csv.writer(f)
for entry in entries:
writer.writerow([
entry['timestamp'],
entry['type'],
entry['amount'],
entry['from'],
entry['to'],
entry['reference'],
entry['description'],
entry['validator_required'],
entry['phase'],
entry['evidence_link'],
entry['status'],
entry['vesting_tranche']
])
return attacker_sc, defender_sc
def main():
parser = argparse.ArgumentParser(
description="Assess work session and recommend SC payout"
)
parser.add_argument('--task-id', required=True,
help='Task ID (e.g., 6_1_3_0)')
parser.add_argument('--mission-leader', required=True,
help='Mission leader conducting assessment')
parser.add_argument('--start-time', required=True,
help='Session start time (ISO format)')
parser.add_argument('--end-time', required=True,
help='Session end time (ISO format)')
parser.add_argument('--attacker-effort-score', type=int, required=True,
choices=range(1, 11), help='Attacker effort score (1-10)')
parser.add_argument('--defender-learning-score', type=int, required=True,
choices=range(1, 11), help='Defender learning score (1-10)')
parser.add_argument('--collaboration-score', type=int, required=True,
choices=range(1, 11), help='Collaboration quality score (1-10)')
parser.add_argument('--session-notes', required=True,
help='Detailed assessment notes')
parser.add_argument('--override-payout', type=int,
help='Override calculated payout percentage (60-100)')
args = parser.parse_args()
# Initialize assessor
assessor = SessionAssessor()
# Load assessment template
template = assessor.load_assessment_template()
# Get task data
task_data = assessor.get_task_data(args.task_id)
# Calculate or use override payout percentage
if args.override_payout:
if args.override_payout < 60 or args.override_payout > 100:
print("❌ Override payout must be between 60-100%")
return
payout_percent = args.override_payout
print(f"⚠️ Using override payout: {payout_percent}%")
else:
payout_percent = assessor.calculate_payout_percentage(
args.attacker_effort_score,
args.defender_learning_score,
args.collaboration_score,
template
)
# Generate session ID
session_id = f"sess_{args.task_id}_{datetime.now().strftime('%Y%m%d_%H%M')}"
# Prepare session data
session_data = {
'session_id': session_id,
'task_id': args.task_id,
'start_time': args.start_time,
'end_time': args.end_time,
'attacker': task_data['attacker_alias'],
'defender': task_data['defender_alias'],
'mission_leader': args.mission_leader,
'attacker_effort_score': args.attacker_effort_score,
'defender_learning_score': args.defender_learning_score,
'collaboration_score': args.collaboration_score,
'total_score': args.attacker_effort_score + args.defender_learning_score + args.collaboration_score,
'recommended_payout_percent': payout_percent,
'session_notes': args.session_notes
}
# Log session
assessor.create_session_log(session_data)
# Create pending SC entries
attacker_sc, defender_sc = assessor.create_pending_sc_entries(task_data, session_data)
# Output results
print(f"✅ Session Assessed: {session_id}")
print(f"📊 Total Score: {session_data['total_score']}/30")
print(f"💰 Recommended Payout: {payout_percent}%")
print(f"⚔️ Attacker SC: {attacker_sc} SC ({task_data['attacker_alias']})")
print(f"🛡️ Defender SC: {defender_sc} SC ({task_data['defender_alias']})")
print(f"📝 Session logged in: ledger/task-management/session-logs.csv")
print(f"⏳ Pending SC created in: ledger/pending-sc/transactions.csv")
print()
print("🔧 Next Steps:")
print("1. Team Captain reviews pending SC entries")
print("2. Community lazy consensus period (48h)")
print("3. SC awards processed via existing validation system")
print(f"4. Check status: python3 scripts/validate-pending-sc.py")
if __name__ == "__main__":
main()