{"id":50472421,"url":"https://github.com/semcod/op3","last_synced_at":"2026-06-01T11:03:33.928Z","repository":{"id":352897721,"uuid":"1217107470","full_name":"semcod/op3","owner":"semcod","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-21T17:15:24.000Z","size":172,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-21T17:19:55.233Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/semcod.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-21T14:52:18.000Z","updated_at":"2026-04-21T17:15:27.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/semcod/op3","commit_stats":null,"previous_names":["semcod/op3"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/semcod/op3","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fop3","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fop3/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fop3/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fop3/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/semcod","download_url":"https://codeload.github.com/semcod/op3/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fop3/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33771630,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-01T02:00:06.963Z","response_time":115,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-01T11:03:33.857Z","updated_at":"2026-06-01T11:03:33.919Z","avatar_url":"https://github.com/semcod.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# op3 — Layered Operations Tree\n\n\n## AI Cost Tracking\n\n![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.2.5-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)\n![AI Cost](https://img.shields.io/badge/AI%20Cost-$2.40-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-5.6h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)\n\n- 🤖 **LLM usage:** $2.4000 (16 commits)\n- 👤 **Human dev:** ~$556 (5.6h @ $100/h, 30min dedup)\n\nGenerated on 2026-04-21 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)\n\n---\n\nLayered infrastructure observation: observe, diff, orchestrate infrastructure as data.\n\n## Overview\n\nop3 provides a unified framework for observing hierarchical infrastructure state across multiple layers:\n\n- **Physical Layer**: Hardware, displays, network, compute\n- **OS Layer**: Kernel, configuration\n- **Runtime Layer**: Containers, compositor\n- **Service Layer**: Containers, systemd services\n- **Endpoint Layer**: HTTP endpoints, TCP ports\n- **Business Layer**: Application health, business logic\n\nBuilt on fraq's fractal data primitives, op3 enables:\n- Deterministic layer scanning with probe system\n- Format adapters (LESS, migration.yaml, snapshot.yaml)\n- Drift detection between intended and actual state\n- Immutable snapshots with diff capabilities\n\n## Installation\n\n```bash\npip install op3\n```\n\n## Quick Start\n\n```python\nfrom opstree import LayerTree, LinearScanner, scan_device\nfrom opstree.layers.builtin import PhysicalLayer, OsLayer, RuntimeLayer\n\n# Register layers\ntree = LayerTree()\ntree.register(PhysicalLayer.display)\ntree.register(OsLayer.kernel)\ntree.register(RuntimeLayer.container)\n\n# Scan a device\ndef execute(cmd: str):\n    # Your SSH/local execution logic\n    stdout, stderr, rc = ...\n    return stdout, stderr, rc\n\nsnapshot = scan_device(\"pi@192.168.188.109\", execute, tree)\nprint(snapshot.to_yaml())\n```\n\n## Format Adapters\n\n```python\nfrom opstree.formats.less import LessAdapter\n\nadapter = LessAdapter()\n\n# Parse LESS to PartialSnapshot\npartial = adapter.parse(open(\"app.doql.less\").read())\n\n# Render Snapshot to LESS\nless_output = adapter.render(snapshot)\n```\n\n## Project Status\n\n**Sprint 4 Complete** (2026-04-21)\n- ✅ Fixed datetime deprecation warnings (datetime.utcnow() → datetime.now(timezone.utc))\n- ✅ All 26 tests passing with zero warnings\n\n**Sprint 5 Complete** (2026-04-21)\n- ✅ Added business.health builtin probe\n- ✅ Added CLI layer filtering option (--layers flag)\n\n**Sprint 6 Complete** (2026-04-21)\n- ✅ Tested op3 with real-world examples from fraq, redeploy, doql\n- ✅ Created examples/ folder with app.doql.less files from all three projects\n- ✅ Enhanced CLI convert command to handle migration.yaml format\n- ✅ All 26 tests passing\n\n**Sprint 3 Complete** (2026-04-21)\n- ✅ CLI with scan, drift, and convert commands\n- ✅ Builtin probes (service.containers, endpoint.http)\n- ✅ Format conversion between LESS, migration.yaml, snapshot.yaml\n- ✅ CLI integration tested\n\n**Sprint 2 Complete** (2026-04-21)\n- ✅ Probe contexts (SSH, Local, Mock)\n- ✅ Builtin probes (RPi display, Linux OS, container runtime)\n- ✅ Format adapters (migration.yaml, snapshot.yaml)\n- ✅ Integration tests with mock context (2 passing)\n- ✅ ExecuteResult handling for compatibility\n\n**Sprint 1 Complete** (2026-04-21)\n- ✅ Layer tree with topological ordering\n- ✅ Builtin layer definitions\n- ✅ Snapshot model with Pydantic\n- ✅ Probe protocol and registry\n- ✅ Linear scanner\n- ✅ Format registry (wraps fraq)\n- ✅ LESS format adapter\n- ✅ Unit tests (16 passing)\n\n## Dependencies\n\n- fraq \u003e= 0.2.15 (core primitives: FraqNode, FormatRegistry, adapters)\n- pydantic \u003e= 2.0\n- pyyaml \u003e= 6.0\n- click \u003e= 8.0\n- jmespath \u003e= 1.0\n- rich \u003e= 13.0\n\n## License\n\nLicensed under Apache-2.0.\n\n\u003c!-- taskill:status:start --\u003e\n\n## Status\n\n_Last updated by [taskill](https://github.com/oqlos/taskill) at 2026-04-25 13:41 UTC_\n\n| Metric | Value |\n|---|---|\n| HEAD | `c33adc1` |\n| Coverage | — |\n| Failing tests | — |\n| Commits in last cycle | 20 |\n\n\u003e Documentation and tooling were expanded: changelog generation, markdown output and formatting, a configuration management system, and a code analysis/relationship mapping engine were added. Tests and CLI were adjusted and some refactorings performed.\n\n\u003c!-- taskill:status:end --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsemcod%2Fop3","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsemcod%2Fop3","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsemcod%2Fop3/lists"}