@ahmed-g-gad/apothem 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +60 -0
- package/LICENSE +21 -0
- package/LICENSES/MIT.txt +18 -0
- package/LICENSES/PSF-2.0.txt +47 -0
- package/README.md +549 -0
- package/bin/README.md +37 -0
- package/bin/apothem.mjs +78 -0
- package/package.json +75 -0
- package/pyproject.toml +347 -0
- package/src/apothem/README.md +52 -0
- package/src/apothem/__init__.py +66 -0
- package/src/apothem/__main__.py +28 -0
- package/src/apothem/_vendor/.keep +0 -0
- package/src/apothem/_vendor/__init__.py +25 -0
- package/src/apothem/_vendor/attr/__init__.py +104 -0
- package/src/apothem/_vendor/attr/__init__.pyi +389 -0
- package/src/apothem/_vendor/attr/_cmp.py +160 -0
- package/src/apothem/_vendor/attr/_cmp.pyi +13 -0
- package/src/apothem/_vendor/attr/_compat.py +99 -0
- package/src/apothem/_vendor/attr/_config.py +31 -0
- package/src/apothem/_vendor/attr/_funcs.py +497 -0
- package/src/apothem/_vendor/attr/_make.py +3406 -0
- package/src/apothem/_vendor/attr/_next_gen.py +674 -0
- package/src/apothem/_vendor/attr/_typing_compat.pyi +15 -0
- package/src/apothem/_vendor/attr/_version_info.py +89 -0
- package/src/apothem/_vendor/attr/_version_info.pyi +9 -0
- package/src/apothem/_vendor/attr/converters.py +162 -0
- package/src/apothem/_vendor/attr/converters.pyi +19 -0
- package/src/apothem/_vendor/attr/exceptions.py +95 -0
- package/src/apothem/_vendor/attr/exceptions.pyi +17 -0
- package/src/apothem/_vendor/attr/filters.py +72 -0
- package/src/apothem/_vendor/attr/filters.pyi +6 -0
- package/src/apothem/_vendor/attr/py.typed +0 -0
- package/src/apothem/_vendor/attr/setters.py +79 -0
- package/src/apothem/_vendor/attr/setters.pyi +20 -0
- package/src/apothem/_vendor/attr/validators.py +750 -0
- package/src/apothem/_vendor/attr/validators.pyi +140 -0
- package/src/apothem/_vendor/attr.LICENSE +21 -0
- package/src/apothem/_vendor/attrs/__init__.py +72 -0
- package/src/apothem/_vendor/attrs/__init__.pyi +314 -0
- package/src/apothem/_vendor/attrs/converters.py +3 -0
- package/src/apothem/_vendor/attrs/exceptions.py +3 -0
- package/src/apothem/_vendor/attrs/filters.py +3 -0
- package/src/apothem/_vendor/attrs/py.typed +0 -0
- package/src/apothem/_vendor/attrs/setters.py +3 -0
- package/src/apothem/_vendor/attrs/validators.py +3 -0
- package/src/apothem/_vendor/attrs.LICENSE +21 -0
- package/src/apothem/_vendor/jsonschema/__init__.py +120 -0
- package/src/apothem/_vendor/jsonschema/__main__.py +6 -0
- package/src/apothem/_vendor/jsonschema/_format.py +546 -0
- package/src/apothem/_vendor/jsonschema/_keywords.py +449 -0
- package/src/apothem/_vendor/jsonschema/_legacy_keywords.py +449 -0
- package/src/apothem/_vendor/jsonschema/_types.py +204 -0
- package/src/apothem/_vendor/jsonschema/_typing.py +29 -0
- package/src/apothem/_vendor/jsonschema/_utils.py +355 -0
- package/src/apothem/_vendor/jsonschema/benchmarks/__init__.py +5 -0
- package/src/apothem/_vendor/jsonschema/benchmarks/const_vs_enum.py +30 -0
- package/src/apothem/_vendor/jsonschema/benchmarks/contains.py +28 -0
- package/src/apothem/_vendor/jsonschema/benchmarks/import_benchmark.py +31 -0
- package/src/apothem/_vendor/jsonschema/benchmarks/issue232/issue.json +2653 -0
- package/src/apothem/_vendor/jsonschema/benchmarks/issue232.py +25 -0
- package/src/apothem/_vendor/jsonschema/benchmarks/json_schema_test_suite.py +12 -0
- package/src/apothem/_vendor/jsonschema/benchmarks/nested_schemas.py +56 -0
- package/src/apothem/_vendor/jsonschema/benchmarks/subcomponents.py +42 -0
- package/src/apothem/_vendor/jsonschema/benchmarks/unused_registry.py +35 -0
- package/src/apothem/_vendor/jsonschema/benchmarks/useless_applicator_schemas.py +106 -0
- package/src/apothem/_vendor/jsonschema/benchmarks/useless_keywords.py +32 -0
- package/src/apothem/_vendor/jsonschema/benchmarks/validator_creation.py +14 -0
- package/src/apothem/_vendor/jsonschema/cli.py +292 -0
- package/src/apothem/_vendor/jsonschema/exceptions.py +490 -0
- package/src/apothem/_vendor/jsonschema/protocols.py +230 -0
- package/src/apothem/_vendor/jsonschema/validators.py +1410 -0
- package/src/apothem/_vendor/jsonschema.LICENSE +19 -0
- package/src/apothem/_vendor/jsonschema_specifications/__init__.py +12 -0
- package/src/apothem/_vendor/jsonschema_specifications/_core.py +38 -0
- package/src/apothem/_vendor/jsonschema_specifications/schemas/draft201909/metaschema.json +42 -0
- package/src/apothem/_vendor/jsonschema_specifications/schemas/draft201909/vocabularies/applicator +56 -0
- package/src/apothem/_vendor/jsonschema_specifications/schemas/draft201909/vocabularies/content +17 -0
- package/src/apothem/_vendor/jsonschema_specifications/schemas/draft201909/vocabularies/core +57 -0
- package/src/apothem/_vendor/jsonschema_specifications/schemas/draft201909/vocabularies/format +14 -0
- package/src/apothem/_vendor/jsonschema_specifications/schemas/draft201909/vocabularies/meta-data +37 -0
- package/src/apothem/_vendor/jsonschema_specifications/schemas/draft201909/vocabularies/validation +98 -0
- package/src/apothem/_vendor/jsonschema_specifications/schemas/draft202012/metaschema.json +58 -0
- package/src/apothem/_vendor/jsonschema_specifications/schemas/draft202012/vocabularies/applicator +48 -0
- package/src/apothem/_vendor/jsonschema_specifications/schemas/draft202012/vocabularies/content +17 -0
- package/src/apothem/_vendor/jsonschema_specifications/schemas/draft202012/vocabularies/core +51 -0
- package/src/apothem/_vendor/jsonschema_specifications/schemas/draft202012/vocabularies/format-annotation +14 -0
- package/src/apothem/_vendor/jsonschema_specifications/schemas/draft202012/vocabularies/format-assertion +14 -0
- package/src/apothem/_vendor/jsonschema_specifications/schemas/draft202012/vocabularies/meta-data +37 -0
- package/src/apothem/_vendor/jsonschema_specifications/schemas/draft202012/vocabularies/unevaluated +15 -0
- package/src/apothem/_vendor/jsonschema_specifications/schemas/draft202012/vocabularies/validation +98 -0
- package/src/apothem/_vendor/jsonschema_specifications/schemas/draft3/metaschema.json +172 -0
- package/src/apothem/_vendor/jsonschema_specifications/schemas/draft4/metaschema.json +149 -0
- package/src/apothem/_vendor/jsonschema_specifications/schemas/draft6/metaschema.json +153 -0
- package/src/apothem/_vendor/jsonschema_specifications/schemas/draft7/metaschema.json +166 -0
- package/src/apothem/_vendor/jsonschema_specifications.LICENSE +19 -0
- package/src/apothem/_vendor/referencing/__init__.py +7 -0
- package/src/apothem/_vendor/referencing/_attrs.py +31 -0
- package/src/apothem/_vendor/referencing/_attrs.pyi +21 -0
- package/src/apothem/_vendor/referencing/_core.py +739 -0
- package/src/apothem/_vendor/referencing/exceptions.py +165 -0
- package/src/apothem/_vendor/referencing/jsonschema.py +642 -0
- package/src/apothem/_vendor/referencing/py.typed +0 -0
- package/src/apothem/_vendor/referencing/retrieval.py +94 -0
- package/src/apothem/_vendor/referencing/typing.py +61 -0
- package/src/apothem/_vendor/referencing.LICENSE +19 -0
- package/src/apothem/_vendor/rpds/__init__.py +251 -0
- package/src/apothem/_vendor/typing_extensions.LICENSE +279 -0
- package/src/apothem/_vendor/typing_extensions.py +4317 -0
- package/src/apothem/_vendor/vendor.txt +22 -0
- package/src/apothem/_vendor/yaml/__init__.py +389 -0
- package/src/apothem/_vendor/yaml/composer.py +138 -0
- package/src/apothem/_vendor/yaml/constructor.py +748 -0
- package/src/apothem/_vendor/yaml/cyaml.py +100 -0
- package/src/apothem/_vendor/yaml/dumper.py +61 -0
- package/src/apothem/_vendor/yaml/emitter.py +1137 -0
- package/src/apothem/_vendor/yaml/error.py +74 -0
- package/src/apothem/_vendor/yaml/events.py +85 -0
- package/src/apothem/_vendor/yaml/loader.py +63 -0
- package/src/apothem/_vendor/yaml/nodes.py +48 -0
- package/src/apothem/_vendor/yaml/parser.py +588 -0
- package/src/apothem/_vendor/yaml/reader.py +185 -0
- package/src/apothem/_vendor/yaml/representer.py +388 -0
- package/src/apothem/_vendor/yaml/resolver.py +226 -0
- package/src/apothem/_vendor/yaml/scanner.py +1435 -0
- package/src/apothem/_vendor/yaml/serializer.py +110 -0
- package/src/apothem/_vendor/yaml/tokens.py +103 -0
- package/src/apothem/_vendor/yaml.LICENSE +20 -0
- package/src/apothem/agents/README.md +60 -0
- package/src/apothem/agents/codebase-explorer.md +91 -0
- package/src/apothem/agents/convention-auditor.md +93 -0
- package/src/apothem/agents/dependency-auditor.md +97 -0
- package/src/apothem/agents/fact-checker.md +84 -0
- package/src/apothem/agents/mcp-builder.md +86 -0
- package/src/apothem/agents/memory-auditor.md +93 -0
- package/src/apothem/agents/prompt-evaluator.md +87 -0
- package/src/apothem/agents/quality-gate.md +103 -0
- package/src/apothem/agents/refactor-surgeon.md +74 -0
- package/src/apothem/agents/research-scout.md +73 -0
- package/src/apothem/agents/security-scanner.md +83 -0
- package/src/apothem/agents/test-runner.md +84 -0
- package/src/apothem/audit/README.md +73 -0
- package/src/apothem/audit/_scan_lib.py +182 -0
- package/src/apothem/audit/analyze_graph.py +260 -0
- package/src/apothem/audit/build_capability_graph.py +607 -0
- package/src/apothem/audit/build_inventory.py +657 -0
- package/src/apothem/audit/build_plans_provenance.py +997 -0
- package/src/apothem/audit/check_links.py +389 -0
- package/src/apothem/audit/classify_artifacts.py +381 -0
- package/src/apothem/audit/deprecated-tokens.txt +10 -0
- package/src/apothem/audit/execute_plans_migration.py +491 -0
- package/src/apothem/audit/known-projects.txt +15 -0
- package/src/apothem/audit/render_capability_index.py +467 -0
- package/src/apothem/audit/render_inventory.py +405 -0
- package/src/apothem/audit/scan_ai_surfaces.py +1125 -0
- package/src/apothem/audit/scan_ai_surfaces_coarse.py +261 -0
- package/src/apothem/audit/scan_drift_features.py +143 -0
- package/src/apothem/audit/scan_frontmatter.py +293 -0
- package/src/apothem/audit/scan_header_coverage.py +1134 -0
- package/src/apothem/audit/scan_plan_leakage.py +540 -0
- package/src/apothem/audit/scan_plans_discipline.py +188 -0
- package/src/apothem/audit/scan_secrets_pii.py +245 -0
- package/src/apothem/audit/scan_stale_tokens.py +296 -0
- package/src/apothem/audit/synthesize_drift.py +205 -0
- package/src/apothem/benchmarks/README.md +33 -0
- package/src/apothem/benchmarks/__init__.py +3 -0
- package/src/apothem/benchmarks/bench_agents.py +63 -0
- package/src/apothem/benchmarks/bench_hooks.py +93 -0
- package/src/apothem/benchmarks/bench_install.py +58 -0
- package/src/apothem/benchmarks/bench_tests.py +93 -0
- package/src/apothem/benchmarks/bench_validate_ecosystem.py +84 -0
- package/src/apothem/cli/README.md +33 -0
- package/src/apothem/cli/__init__.py +229 -0
- package/src/apothem/cli/_cmd_completion.py +88 -0
- package/src/apothem/cli/_cmd_diff.py +181 -0
- package/src/apothem/cli/_cmd_doctor.py +143 -0
- package/src/apothem/cli/_cmd_harnesses.py +167 -0
- package/src/apothem/cli/_cmd_install.py +327 -0
- package/src/apothem/cli/_cmd_migrate_workspace.py +143 -0
- package/src/apothem/cli/_cmd_profile.py +341 -0
- package/src/apothem/cli/_cmd_status.py +180 -0
- package/src/apothem/cli/_cmd_uninstall.py +215 -0
- package/src/apothem/cli/_cmd_update.py +397 -0
- package/src/apothem/cli/_cmd_verify.py +194 -0
- package/src/apothem/cli/_common_flags.py +90 -0
- package/src/apothem/cli/_epilogs.py +296 -0
- package/src/apothem/cli/_helpers.py +857 -0
- package/src/apothem/cli/_json_formatter.py +21 -0
- package/src/apothem/cli/_materialize.py +376 -0
- package/src/apothem/cli/completions/apothem.bash +30 -0
- package/src/apothem/cli/completions/apothem.fish +19 -0
- package/src/apothem/cli/completions/apothem.ps1 +27 -0
- package/src/apothem/cli/completions/apothem.zsh +42 -0
- package/src/apothem/cli/reference_export.py +126 -0
- package/src/apothem/commands/README.md +125 -0
- package/src/apothem/commands/a11y-audit.md +203 -0
- package/src/apothem/commands/architecture-review.md +194 -0
- package/src/apothem/commands/audit.md +165 -0
- package/src/apothem/commands/code-audit.md +218 -0
- package/src/apothem/commands/code-review.md +193 -0
- package/src/apothem/commands/dependency-audit.md +209 -0
- package/src/apothem/commands/docs-review.md +199 -0
- package/src/apothem/commands/elevate.md +285 -0
- package/src/apothem/commands/eval.md +149 -0
- package/src/apothem/commands/fortress.md +172 -0
- package/src/apothem/commands/freshify.md +168 -0
- package/src/apothem/commands/github-deploy-fresh.md +178 -0
- package/src/apothem/commands/github-deploy-next.md +167 -0
- package/src/apothem/commands/perf-audit.md +198 -0
- package/src/apothem/commands/plan-amend.md +104 -0
- package/src/apothem/commands/plan-audit.md +127 -0
- package/src/apothem/commands/plan-design.md +257 -0
- package/src/apothem/commands/plan-execute.md +495 -0
- package/src/apothem/commands/plan-generate.md +351 -0
- package/src/apothem/commands/plan-review.md +555 -0
- package/src/apothem/commands/plan-spec.md +359 -0
- package/src/apothem/commands/plan-status.md +222 -0
- package/src/apothem/commands/plan.md +173 -0
- package/src/apothem/commands/projectify.md +142 -0
- package/src/apothem/commands/release-readiness.md +142 -0
- package/src/apothem/commands/research-analysis.md +241 -0
- package/src/apothem/commands/research-design.md +231 -0
- package/src/apothem/commands/research-disseminate.md +225 -0
- package/src/apothem/commands/research-experiment.md +232 -0
- package/src/apothem/commands/research-ideate.md +213 -0
- package/src/apothem/commands/research-paper.md +252 -0
- package/src/apothem/commands/research-proposal.md +220 -0
- package/src/apothem/commands/research-publish.md +255 -0
- package/src/apothem/commands/research-review.md +251 -0
- package/src/apothem/commands/research-sources.md +266 -0
- package/src/apothem/commands/research-spec.md +255 -0
- package/src/apothem/commands/research-synthesis.md +233 -0
- package/src/apothem/commands/research-theory.md +218 -0
- package/src/apothem/commands/research.md +181 -0
- package/src/apothem/commands/security-audit.md +196 -0
- package/src/apothem/commands/supply-chain-audit.md +192 -0
- package/src/apothem/commands/test-suite.md +146 -0
- package/src/apothem/commands/threat-model-audit.md +199 -0
- package/src/apothem/commands/ux-review.md +202 -0
- package/src/apothem/commands/workflow.md +162 -0
- package/src/apothem/conformity/README.md +173 -0
- package/src/apothem/conformity/__init__.py +1 -0
- package/src/apothem/conformity/_grep_base.py +93 -0
- package/src/apothem/conformity/agent_capability_grep.py +306 -0
- package/src/apothem/conformity/agents_md_coverage_grep.py +382 -0
- package/src/apothem/conformity/agnosticism_grep.py +311 -0
- package/src/apothem/conformity/always_on_budget_grep.py +318 -0
- package/src/apothem/conformity/bare_except_grep.py +115 -0
- package/src/apothem/conformity/binding_reciprocity_grep.py +151 -0
- package/src/apothem/conformity/brand_mark_grep.py +272 -0
- package/src/apothem/conformity/commented_out_code_grep.py +176 -0
- package/src/apothem/conformity/completion_claim_grep.py +169 -0
- package/src/apothem/conformity/conventional_commit_grep.py +319 -0
- package/src/apothem/conformity/copilot_instructions_presence_grep.py +324 -0
- package/src/apothem/conformity/cross_platform_matrix_grep.py +297 -0
- package/src/apothem/conformity/determinism_grep.py +306 -0
- package/src/apothem/conformity/diagram_staleness_grep.py +154 -0
- package/src/apothem/conformity/dynamism_grep.py +284 -0
- package/src/apothem/conformity/editorconfig_presence_grep.py +281 -0
- package/src/apothem/conformity/file_header_grep.py +502 -0
- package/src/apothem/conformity/freshness_token_grep.py +233 -0
- package/src/apothem/conformity/frontmatter_grep.py +274 -0
- package/src/apothem/conformity/frontmatter_value_grep.py +386 -0
- package/src/apothem/conformity/gate.py +1386 -0
- package/src/apothem/conformity/gitattributes_presence_grep.py +238 -0
- package/src/apothem/conformity/harden_runner_grep.py +320 -0
- package/src/apothem/conformity/hedging_grep.py +129 -0
- package/src/apothem/conformity/license_author_consistency_grep.py +204 -0
- package/src/apothem/conformity/link_check.py +327 -0
- package/src/apothem/conformity/magic_number_grep.py +182 -0
- package/src/apothem/conformity/multi_surface_coherence_grep.py +620 -0
- package/src/apothem/conformity/naming_grep.py +224 -0
- package/src/apothem/conformity/no_global_plans_grep.py +339 -0
- package/src/apothem/conformity/no_toplevel_docs_grep.py +120 -0
- package/src/apothem/conformity/oidc_trusted_publishing_grep.py +291 -0
- package/src/apothem/conformity/option_annotation_grep.py +352 -0
- package/src/apothem/conformity/orphan_output_grep.py +206 -0
- package/src/apothem/conformity/permissions_minimum_scope_grep.py +299 -0
- package/src/apothem/conformity/plain_language_grep.py +559 -0
- package/src/apothem/conformity/plan_next_step_consistency_grep.py +450 -0
- package/src/apothem/conformity/plan_suite_structure_grep.py +534 -0
- package/src/apothem/conformity/plans_discipline_language_grep.py +245 -0
- package/src/apothem/conformity/production_ready_pr_grep.py +200 -0
- package/src/apothem/conformity/recommend_next_step_grep.py +250 -0
- package/src/apothem/conformity/redundancy_grep.py +401 -0
- package/src/apothem/conformity/reference_token_grep.py +230 -0
- package/src/apothem/conformity/registry_capability_consistency_grep.py +368 -0
- package/src/apothem/conformity/secret_leak_grep.py +193 -0
- package/src/apothem/conformity/semver_stability_grep.py +358 -0
- package/src/apothem/conformity/smoke_install_grep.py +194 -0
- package/src/apothem/conformity/static_version_grep.py +284 -0
- package/src/apothem/conformity/token_efficiency_grep.py +185 -0
- package/src/apothem/conformity/unpinned_action_grep.py +115 -0
- package/src/apothem/conformity/user_confirm_grep.py +74 -0
- package/src/apothem/conformity/workflow_concurrency_grep.py +283 -0
- package/src/apothem/harnesses/README.md +63 -0
- package/src/apothem/harnesses/__init__.py +16 -0
- package/src/apothem/harnesses/_shared/README.md +36 -0
- package/src/apothem/harnesses/_shared/__init__.py +12 -0
- package/src/apothem/harnesses/_shared/install_driver.py +281 -0
- package/src/apothem/harnesses/_shared/install_driver_apply.py +612 -0
- package/src/apothem/harnesses/_shared/install_driver_backup.py +535 -0
- package/src/apothem/harnesses/_shared/install_driver_converters.py +310 -0
- package/src/apothem/harnesses/_shared/install_driver_lifecycle.py +495 -0
- package/src/apothem/harnesses/_shared/install_driver_materialize.py +675 -0
- package/src/apothem/harnesses/_shared/install_driver_merge.py +656 -0
- package/src/apothem/harnesses/_shared/install_driver_pathsafety.py +137 -0
- package/src/apothem/harnesses/_shared/install_driver_planvalidation.py +240 -0
- package/src/apothem/harnesses/_shared/install_driver_removal.py +366 -0
- package/src/apothem/harnesses/_shared/install_driver_treeops.py +248 -0
- package/src/apothem/harnesses/_shared/install_driver_types.py +330 -0
- package/src/apothem/harnesses/_shared/wrapper_factories.py +448 -0
- package/src/apothem/harnesses/antigravity/STANDARD-CONVENTION-PIN.md +91 -0
- package/src/apothem/harnesses/antigravity/__init__.py +70 -0
- package/src/apothem/harnesses/antigravity/capabilities.yml +40 -0
- package/src/apothem/harnesses/antigravity/install.py +63 -0
- package/src/apothem/harnesses/antigravity/templates/GEMINI.md +40 -0
- package/src/apothem/harnesses/antigravity/templates/plugin.json +5 -0
- package/src/apothem/harnesses/antigravity/uninstall.py +22 -0
- package/src/apothem/harnesses/antigravity/update.py +10 -0
- package/src/apothem/harnesses/antigravity/verify.py +11 -0
- package/src/apothem/harnesses/claude_code/STANDARD-CONVENTION-PIN.md +65 -0
- package/src/apothem/harnesses/claude_code/__init__.py +107 -0
- package/src/apothem/harnesses/claude_code/capabilities.yml +42 -0
- package/src/apothem/harnesses/claude_code/install.py +147 -0
- package/src/apothem/harnesses/claude_code/templates/settings.json +351 -0
- package/src/apothem/harnesses/claude_code/uninstall.py +23 -0
- package/src/apothem/harnesses/claude_code/update.py +10 -0
- package/src/apothem/harnesses/claude_code/verify.py +11 -0
- package/src/apothem/harnesses/codebuddy/STANDARD-CONVENTION-PIN.md +74 -0
- package/src/apothem/harnesses/codebuddy/__init__.py +49 -0
- package/src/apothem/harnesses/codebuddy/capabilities.yml +34 -0
- package/src/apothem/harnesses/codebuddy/install.py +40 -0
- package/src/apothem/harnesses/codebuddy/templates/apothem-rules.md +37 -0
- package/src/apothem/harnesses/codebuddy/uninstall.py +25 -0
- package/src/apothem/harnesses/codebuddy/update.py +10 -0
- package/src/apothem/harnesses/codebuddy/verify.py +11 -0
- package/src/apothem/harnesses/codex/STANDARD-CONVENTION-PIN.md +79 -0
- package/src/apothem/harnesses/codex/__init__.py +72 -0
- package/src/apothem/harnesses/codex/capabilities.yml +40 -0
- package/src/apothem/harnesses/codex/install.py +69 -0
- package/src/apothem/harnesses/codex/templates/AGENTS.md +40 -0
- package/src/apothem/harnesses/codex/templates/hooks.json +127 -0
- package/src/apothem/harnesses/codex/uninstall.py +23 -0
- package/src/apothem/harnesses/codex/update.py +10 -0
- package/src/apothem/harnesses/codex/verify.py +11 -0
- package/src/apothem/harnesses/cursor/STANDARD-CONVENTION-PIN.md +79 -0
- package/src/apothem/harnesses/cursor/__init__.py +48 -0
- package/src/apothem/harnesses/cursor/capabilities.yml +42 -0
- package/src/apothem/harnesses/cursor/install.py +38 -0
- package/src/apothem/harnesses/cursor/templates/apothem-rules.mdc +40 -0
- package/src/apothem/harnesses/cursor/uninstall.py +25 -0
- package/src/apothem/harnesses/cursor/update.py +10 -0
- package/src/apothem/harnesses/cursor/verify.py +11 -0
- package/src/apothem/harnesses/gemini_cli/STANDARD-CONVENTION-PIN.md +102 -0
- package/src/apothem/harnesses/gemini_cli/__init__.py +52 -0
- package/src/apothem/harnesses/gemini_cli/capabilities.yml +43 -0
- package/src/apothem/harnesses/gemini_cli/install.py +43 -0
- package/src/apothem/harnesses/gemini_cli/templates/GEMINI.md +38 -0
- package/src/apothem/harnesses/gemini_cli/uninstall.py +25 -0
- package/src/apothem/harnesses/gemini_cli/update.py +10 -0
- package/src/apothem/harnesses/gemini_cli/verify.py +11 -0
- package/src/apothem/harnesses/github_copilot/STANDARD-CONVENTION-PIN.md +84 -0
- package/src/apothem/harnesses/github_copilot/__init__.py +47 -0
- package/src/apothem/harnesses/github_copilot/capabilities.yml +42 -0
- package/src/apothem/harnesses/github_copilot/install.py +40 -0
- package/src/apothem/harnesses/github_copilot/templates/copilot-instructions.md +33 -0
- package/src/apothem/harnesses/github_copilot/uninstall.py +25 -0
- package/src/apothem/harnesses/github_copilot/update.py +10 -0
- package/src/apothem/harnesses/github_copilot/verify.py +11 -0
- package/src/apothem/harnesses/glm/STANDARD-CONVENTION-PIN.md +77 -0
- package/src/apothem/harnesses/glm/__init__.py +56 -0
- package/src/apothem/harnesses/glm/capabilities.yml +33 -0
- package/src/apothem/harnesses/glm/install.py +45 -0
- package/src/apothem/harnesses/glm/templates/glm.toml +58 -0
- package/src/apothem/harnesses/glm/uninstall.py +25 -0
- package/src/apothem/harnesses/glm/update.py +10 -0
- package/src/apothem/harnesses/glm/verify.py +11 -0
- package/src/apothem/harnesses/hermes/STANDARD-CONVENTION-PIN.md +57 -0
- package/src/apothem/harnesses/hermes/__init__.py +33 -0
- package/src/apothem/harnesses/hermes/capabilities.yml +36 -0
- package/src/apothem/harnesses/hermes/install.py +17 -0
- package/src/apothem/harnesses/hermes/materializer.py +35 -0
- package/src/apothem/harnesses/hermes/uninstall.py +33 -0
- package/src/apothem/harnesses/hermes/update.py +10 -0
- package/src/apothem/harnesses/hermes/verify.py +11 -0
- package/src/apothem/harnesses/kimi_code/STANDARD-CONVENTION-PIN.md +128 -0
- package/src/apothem/harnesses/kimi_code/__init__.py +59 -0
- package/src/apothem/harnesses/kimi_code/capabilities.yml +40 -0
- package/src/apothem/harnesses/kimi_code/install.py +42 -0
- package/src/apothem/harnesses/kimi_code/templates/AGENTS.md +43 -0
- package/src/apothem/harnesses/kimi_code/uninstall.py +27 -0
- package/src/apothem/harnesses/kimi_code/update.py +10 -0
- package/src/apothem/harnesses/kimi_code/verify.py +11 -0
- package/src/apothem/harnesses/kiro/STANDARD-CONVENTION-PIN.md +77 -0
- package/src/apothem/harnesses/kiro/__init__.py +49 -0
- package/src/apothem/harnesses/kiro/capabilities.yml +36 -0
- package/src/apothem/harnesses/kiro/install.py +39 -0
- package/src/apothem/harnesses/kiro/templates/apothem-rules.md +36 -0
- package/src/apothem/harnesses/kiro/uninstall.py +25 -0
- package/src/apothem/harnesses/kiro/update.py +10 -0
- package/src/apothem/harnesses/kiro/verify.py +11 -0
- package/src/apothem/harnesses/open_claw/STANDARD-CONVENTION-PIN.md +62 -0
- package/src/apothem/harnesses/open_claw/__init__.py +35 -0
- package/src/apothem/harnesses/open_claw/capabilities.yml +35 -0
- package/src/apothem/harnesses/open_claw/install.py +17 -0
- package/src/apothem/harnesses/open_claw/materializer.py +36 -0
- package/src/apothem/harnesses/open_claw/uninstall.py +32 -0
- package/src/apothem/harnesses/open_claw/update.py +10 -0
- package/src/apothem/harnesses/open_claw/verify.py +11 -0
- package/src/apothem/harnesses/opencode/STANDARD-CONVENTION-PIN.md +76 -0
- package/src/apothem/harnesses/opencode/__init__.py +35 -0
- package/src/apothem/harnesses/opencode/capabilities.yml +43 -0
- package/src/apothem/harnesses/opencode/install.py +17 -0
- package/src/apothem/harnesses/opencode/materializer.py +31 -0
- package/src/apothem/harnesses/opencode/uninstall.py +34 -0
- package/src/apothem/harnesses/opencode/update.py +10 -0
- package/src/apothem/harnesses/opencode/verify.py +11 -0
- package/src/apothem/harnesses/qwen_code/STANDARD-CONVENTION-PIN.md +87 -0
- package/src/apothem/harnesses/qwen_code/__init__.py +37 -0
- package/src/apothem/harnesses/qwen_code/capabilities.yml +43 -0
- package/src/apothem/harnesses/qwen_code/install.py +19 -0
- package/src/apothem/harnesses/qwen_code/materializer.py +174 -0
- package/src/apothem/harnesses/qwen_code/templates/QWEN.md +30 -0
- package/src/apothem/harnesses/qwen_code/uninstall.py +34 -0
- package/src/apothem/harnesses/qwen_code/update.py +10 -0
- package/src/apothem/harnesses/qwen_code/verify.py +11 -0
- package/src/apothem/harnesses/trae/STANDARD-CONVENTION-PIN.md +70 -0
- package/src/apothem/harnesses/trae/__init__.py +49 -0
- package/src/apothem/harnesses/trae/capabilities.yml +34 -0
- package/src/apothem/harnesses/trae/install.py +38 -0
- package/src/apothem/harnesses/trae/templates/apothem-rules.md +37 -0
- package/src/apothem/harnesses/trae/uninstall.py +25 -0
- package/src/apothem/harnesses/trae/update.py +10 -0
- package/src/apothem/harnesses/trae/verify.py +11 -0
- package/src/apothem/harnesses/windsurf/STANDARD-CONVENTION-PIN.md +91 -0
- package/src/apothem/harnesses/windsurf/__init__.py +52 -0
- package/src/apothem/harnesses/windsurf/capabilities.yml +40 -0
- package/src/apothem/harnesses/windsurf/install.py +41 -0
- package/src/apothem/harnesses/windsurf/templates/apothem-rules.md +37 -0
- package/src/apothem/harnesses/windsurf/uninstall.py +25 -0
- package/src/apothem/harnesses/windsurf/update.py +10 -0
- package/src/apothem/harnesses/windsurf/verify.py +11 -0
- package/src/apothem/harnesses/zed/STANDARD-CONVENTION-PIN.md +92 -0
- package/src/apothem/harnesses/zed/__init__.py +57 -0
- package/src/apothem/harnesses/zed/capabilities.yml +38 -0
- package/src/apothem/harnesses/zed/install.py +41 -0
- package/src/apothem/harnesses/zed/templates/apothem-rules.md +32 -0
- package/src/apothem/harnesses/zed/uninstall.py +28 -0
- package/src/apothem/harnesses/zed/update.py +10 -0
- package/src/apothem/harnesses/zed/verify.py +11 -0
- package/src/apothem/hooks/README.md +81 -0
- package/src/apothem/hooks/__init__.py +24 -0
- package/src/apothem/hooks/askuserquestion_validator.py +380 -0
- package/src/apothem/hooks/dispatch.py +296 -0
- package/src/apothem/hooks/emit_hook_context.py +444 -0
- package/src/apothem/hooks/hooks.json +318 -0
- package/src/apothem/hooks/lib/README.md +39 -0
- package/src/apothem/hooks/lib/__init__.py +18 -0
- package/src/apothem/hooks/lib/bootstrap.ps1 +129 -0
- package/src/apothem/hooks/lib/bootstrap.sh +103 -0
- package/src/apothem/hooks/lib/events.py +51 -0
- package/src/apothem/hooks/lib/find-pwsh.ps1 +78 -0
- package/src/apothem/hooks/lib/find-pwsh.sh +76 -0
- package/src/apothem/hooks/lib/find-python.ps1 +63 -0
- package/src/apothem/hooks/lib/find-python.sh +97 -0
- package/src/apothem/hooks/lib/log.py +43 -0
- package/src/apothem/hooks/lib/resolve_root.py +264 -0
- package/src/apothem/hooks/messages/postcompact.md +14 -0
- package/src/apothem/hooks/messages/posttooluse-proactive-compaction.md +46 -0
- package/src/apothem/hooks/messages/precompact.md +14 -0
- package/src/apothem/hooks/messages/pretooluse-askuserquestion-recommended.md +65 -0
- package/src/apothem/hooks/messages/pretooluse-bash-plan-guard.md +97 -0
- package/src/apothem/hooks/messages/pretooluse-bash.md +39 -0
- package/src/apothem/hooks/messages/pretooluse-conformity.md +70 -0
- package/src/apothem/hooks/messages/pretooluse-dependency-guard.md +21 -0
- package/src/apothem/hooks/messages/pretooluse-edit-header-guard.md +61 -0
- package/src/apothem/hooks/messages/pretooluse-edit.md +21 -0
- package/src/apothem/hooks/messages/pretooluse-eval-guard.md +39 -0
- package/src/apothem/hooks/messages/pretooluse-notebookedit.md +11 -0
- package/src/apothem/hooks/messages/pretooluse-write-header-guard.md +45 -0
- package/src/apothem/hooks/messages/pretooluse-write-plan-guard.md +72 -0
- package/src/apothem/hooks/messages/pretooluse-write.md +21 -0
- package/src/apothem/hooks/messages/sessionstart.md +15 -0
- package/src/apothem/hooks/messages/stop.md +27 -0
- package/src/apothem/hooks/proactive_compaction_tracker.py +327 -0
- package/src/apothem/hooks/session_start_bootstrap.py +472 -0
- package/src/apothem/lib/README.md +42 -0
- package/src/apothem/lib/__init__.py +13 -0
- package/src/apothem/lib/atomic_io.py +189 -0
- package/src/apothem/lib/auditor.py +687 -0
- package/src/apothem/lib/clean_slate.py +396 -0
- package/src/apothem/lib/contexts.py +352 -0
- package/src/apothem/lib/data_home.py +255 -0
- package/src/apothem/lib/frontmatter.py +101 -0
- package/src/apothem/lib/harness_materializer.py +213 -0
- package/src/apothem/lib/harness_protocol.py +59 -0
- package/src/apothem/lib/harness_registry.py +282 -0
- package/src/apothem/lib/harness_registry_data.py +843 -0
- package/src/apothem/lib/install_ledger.py +347 -0
- package/src/apothem/lib/learning.py +540 -0
- package/src/apothem/lib/memory.py +347 -0
- package/src/apothem/lib/parallel_sweep.py +234 -0
- package/src/apothem/lib/plan_tiers.py +200 -0
- package/src/apothem/lib/plugin_bootstrap.py +132 -0
- package/src/apothem/lib/plugin_tree.py +599 -0
- package/src/apothem/lib/profile.py +755 -0
- package/src/apothem/lib/profile_projection.py +198 -0
- package/src/apothem/lib/propagation-manifest.yaml +878 -0
- package/src/apothem/lib/propagation.py +220 -0
- package/src/apothem/lib/python_resolver.py +189 -0
- package/src/apothem/lib/reporter.py +62 -0
- package/src/apothem/lib/workspace_migration.py +323 -0
- package/src/apothem/output-styles/README.md +41 -0
- package/src/apothem/output-styles/concise-engineer.md +49 -0
- package/src/apothem/output-styles/default-architect.md +52 -0
- package/src/apothem/output-styles/default.md +113 -0
- package/src/apothem/output-styles/forensic-auditor.md +63 -0
- package/src/apothem/py.typed +0 -0
- package/src/apothem/rules/README.md +121 -0
- package/src/apothem/rules/agent-capability-discipline-matrix.md +89 -0
- package/src/apothem/rules/agent-capability-discipline.md +78 -0
- package/src/apothem/rules/agent-orchestration-patterns.md +144 -0
- package/src/apothem/rules/agent-orchestration.md +65 -0
- package/src/apothem/rules/agents-md-convention.md +86 -0
- package/src/apothem/rules/agile-sprints-elements.md +135 -0
- package/src/apothem/rules/agile-sprints.md +64 -0
- package/src/apothem/rules/agnostic-posture-checklist.md +47 -0
- package/src/apothem/rules/agnostic-posture.md +48 -0
- package/src/apothem/rules/authoritative-referencing-quotation.md +50 -0
- package/src/apothem/rules/authoritative-referencing.md +66 -0
- package/src/apothem/rules/authority-inquiry-categories.md +58 -0
- package/src/apothem/rules/authority-inquiry.md +54 -0
- package/src/apothem/rules/auto-memory-topic-files.md +86 -0
- package/src/apothem/rules/auto-memory.md +67 -0
- package/src/apothem/rules/bidirectional-binding.md +123 -0
- package/src/apothem/rules/canonical-layout-reporting-tiers.md +212 -0
- package/src/apothem/rules/canonical-layout.md +60 -0
- package/src/apothem/rules/clean-architecture-layers.md +186 -0
- package/src/apothem/rules/clean-room-generation-protocols.md +124 -0
- package/src/apothem/rules/clean-room-generation.md +59 -0
- package/src/apothem/rules/code-craft-conventions.md +101 -0
- package/src/apothem/rules/code-craft-markdown.md +138 -0
- package/src/apothem/rules/code-craft-python.md +154 -0
- package/src/apothem/rules/code-craft-shell.md +192 -0
- package/src/apothem/rules/cognitive-identity-techniques.md +180 -0
- package/src/apothem/rules/cognitive-identity.md +81 -0
- package/src/apothem/rules/context-management-budget.md +46 -0
- package/src/apothem/rules/context-management-protocol.md +161 -0
- package/src/apothem/rules/context-management-scratch.md +128 -0
- package/src/apothem/rules/context-management.md +85 -0
- package/src/apothem/rules/definitiveness-virtues.md +67 -0
- package/src/apothem/rules/definitiveness.md +58 -0
- package/src/apothem/rules/determinism.md +81 -0
- package/src/apothem/rules/disclosure-ledger-markers.md +58 -0
- package/src/apothem/rules/disclosure-ledger.md +52 -0
- package/src/apothem/rules/dynamism.md +38 -0
- package/src/apothem/rules/etc-extension.md +57 -0
- package/src/apothem/rules/expertise-posture-elements.md +68 -0
- package/src/apothem/rules/expertise-posture.md +54 -0
- package/src/apothem/rules/freshness-facade.md +64 -0
- package/src/apothem/rules/harness-adapter-shape-schemas.md +162 -0
- package/src/apothem/rules/harness-adapter-shape.md +42 -0
- package/src/apothem/rules/host-discovery-manifests.md +50 -0
- package/src/apothem/rules/host-discovery.md +56 -0
- package/src/apothem/rules/i18n-discipline-locale-cohorts.md +120 -0
- package/src/apothem/rules/i18n-discipline.md +70 -0
- package/src/apothem/rules/interactive-questions-canonical-shapes.md +590 -0
- package/src/apothem/rules/interactive-questions-detail.md +41 -0
- package/src/apothem/rules/interactive-questions-sweep-matchers.md +184 -0
- package/src/apothem/rules/interactive-questions.md +89 -0
- package/src/apothem/rules/large-file-generation.md +112 -0
- package/src/apothem/rules/large-file-reading.md +59 -0
- package/src/apothem/rules/living-docs.md +85 -0
- package/src/apothem/rules/multi-agent-workflow.md +57 -0
- package/src/apothem/rules/operational-mandates-expanded.md +78 -0
- package/src/apothem/rules/operational-mandates.md +88 -0
- package/src/apothem/rules/option-annotation-form.md +60 -0
- package/src/apothem/rules/option-annotation.md +45 -0
- package/src/apothem/rules/own-voice-reimplementation.md +86 -0
- package/src/apothem/rules/performance-discipline.md +91 -0
- package/src/apothem/rules/persistent-conventions-vigilance-checklist.md +54 -0
- package/src/apothem/rules/persistent-conventions-vigilance.md +61 -0
- package/src/apothem/rules/plain-language.md +56 -0
- package/src/apothem/rules/planning-techniques.md +130 -0
- package/src/apothem/rules/pre-emission-gate-bars.md +86 -0
- package/src/apothem/rules/pre-emission-gate.md +54 -0
- package/src/apothem/rules/production-ready-prs-surfaces.md +162 -0
- package/src/apothem/rules/production-ready-prs.md +83 -0
- package/src/apothem/rules/propagation.md +63 -0
- package/src/apothem/rules/recommend-next-step.md +106 -0
- package/src/apothem/rules/refactoring-discipline.md +76 -0
- package/src/apothem/rules/session-closure.md +44 -0
- package/src/apothem/rules/sota-elevation-exemplars.md +76 -0
- package/src/apothem/rules/sota-elevation.md +52 -0
- package/src/apothem/rules/source-accessibility.md +58 -0
- package/src/apothem/rules/surgical-manipulation.md +48 -0
- package/src/apothem/rules/systemic-participation-relations.md +108 -0
- package/src/apothem/rules/systemic-participation.md +70 -0
- package/src/apothem/rules/ten-dimension-check-dimensions.md +52 -0
- package/src/apothem/rules/ten-dimension-check.md +59 -0
- package/src/apothem/rules/token-budget-discipline.md +81 -0
- package/src/apothem/rules/token-efficiency-rewrite-protocol.md +79 -0
- package/src/apothem/rules/token-efficiency-rewrite.md +77 -0
- package/src/apothem/rules/tool-use-discipline.md +48 -0
- package/src/apothem/rules/visual-leverage.md +102 -0
- package/src/apothem/schemas/NOTICE.md +9 -0
- package/src/apothem/schemas/README.md +104 -0
- package/src/apothem/schemas/__init__.py +176 -0
- package/src/apothem/schemas/advisory-finding.schema.json +111 -0
- package/src/apothem/schemas/agent.schema.json +106 -0
- package/src/apothem/schemas/authorship-header.txt +1 -0
- package/src/apothem/schemas/cohort-manifest.yaml +248 -0
- package/src/apothem/schemas/cohort-metadata-vocabulary.yaml +168 -0
- package/src/apothem/schemas/cohort.schema.json +113 -0
- package/src/apothem/schemas/command.schema.json +68 -0
- package/src/apothem/schemas/compatibility-matrix.yaml +432 -0
- package/src/apothem/schemas/context-fragment.schema.json +64 -0
- package/src/apothem/schemas/freshness-token-denylist.txt +51 -0
- package/src/apothem/schemas/handoff-manifest.yaml +353 -0
- package/src/apothem/schemas/header-exceptions.txt +141 -0
- package/src/apothem/schemas/header-visibility.yaml +39 -0
- package/src/apothem/schemas/learning-signal.schema.json +46 -0
- package/src/apothem/schemas/memory-record.schema.json +61 -0
- package/src/apothem/schemas/output-style.schema.json +40 -0
- package/src/apothem/schemas/plan.schema.json +51 -0
- package/src/apothem/schemas/plugin.schema.json +83 -0
- package/src/apothem/schemas/profile.example.yaml +70 -0
- package/src/apothem/schemas/profile.minimal.yaml +6 -0
- package/src/apothem/schemas/profile.schema.json +396 -0
- package/src/apothem/schemas/reference-token-denylist.txt +25 -0
- package/src/apothem/schemas/skill.schema.json +75 -0
- package/src/apothem/skills/README.md +93 -0
- package/src/apothem/skills/dependency-upgrade/SKILL.md +105 -0
- package/src/apothem/skills/dev-toolkit/SKILL.md +120 -0
- package/src/apothem/skills/diagram-authoring/SKILL.md +113 -0
- package/src/apothem/skills/document-authoring/SKILL.md +118 -0
- package/src/apothem/skills/ecosystem-audit/SKILL.md +108 -0
- package/src/apothem/skills/ecosystem-audit/references/audit-fortress.md +85 -0
- package/src/apothem/skills/ecosystem-audit/references/procedure.md +162 -0
- package/src/apothem/skills/eval-harness/SKILL.md +88 -0
- package/src/apothem/skills/incident-runbook/SKILL.md +92 -0
- package/src/apothem/skills/multi-source-research/SKILL.md +90 -0
- package/src/apothem/skills/plan-suite/SKILL.md +118 -0
- package/src/apothem/skills/plan-suite/master_template.md +1324 -0
- package/src/apothem/skills/projectify/SKILL.md +117 -0
- package/src/apothem/skills/prompt-engineering/SKILL.md +122 -0
- package/src/apothem/skills/refactor-extract/SKILL.md +85 -0
- package/src/apothem/skills/research-suite/SKILL.md +170 -0
- package/src/apothem/skills/research-suite/references/directory-structure.md +47 -0
- package/src/apothem/skills/research-suite/references/lifecycle.md +67 -0
- package/src/apothem/skills/research-suite/references/principal-investigator-framework.md +37 -0
- package/src/apothem/skills/research-suite/references/rigor-mandates.md +30 -0
- package/src/apothem/skills/research-suite/research_template.md +476 -0
- package/src/apothem/skills/secret-rotation/SKILL.md +87 -0
- package/src/apothem/skills/source-synthesis/SKILL.md +92 -0
- package/src/apothem/skills/surgical-guard/SKILL.md +118 -0
- package/src/apothem/skills/test-authoring/SKILL.md +85 -0
- package/src/apothem/skills/vuln-triage/SKILL.md +91 -0
- package/src/apothem/skills/workflow/SKILL.md +139 -0
- package/src/apothem/statuslines/README.md +26 -0
- package/src/apothem/statuslines/__init__.py +20 -0
- package/src/apothem/statuslines/conformity.json +5 -0
- package/src/apothem/statuslines/render.py +334 -0
- package/src/apothem/statuslines/statusline.md +50 -0
- package/src/apothem/templates/README.md +43 -0
- package/src/apothem/templates/agents-md-template.md +80 -0
- package/src/apothem/templates/consideration-log.md +39 -0
- package/src/apothem/templates/expertise-gap-log.md +56 -0
- package/src/apothem/templates/master-index-template.md +93 -0
- package/src/apothem/templates/potency-map.md +53 -0
- package/src/apothem/templates/preservation-audit.md +60 -0
- package/src/apothem/templates/question-resolution-audit.md +52 -0
- package/src/apothem/templates/trace-matrix-template.md +77 -0
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
"""Validate frontmatter VALUES against the per-class JSON Schema enum/pattern constraints.
|
|
4
|
+
|
|
5
|
+
Why this validator exists. The sibling ``frontmatter_grep`` matcher checks
|
|
6
|
+
that an artifact carries the required frontmatter *keys* (and that the keys are
|
|
7
|
+
kebab-case); it deliberately does not parse or constrain the *values* — and it
|
|
8
|
+
rejects camelCase keys, so it is not run against the agent corpus whose schema
|
|
9
|
+
declares camelCase optional fields (``permissionMode``, ``disallowedTools``,
|
|
10
|
+
``maxTurns``, …). The doc-example test ``tests/unit/docs/test_frontmatter_examples.py``
|
|
11
|
+
checks documented example *keys* against the shipped-agent key union, not the
|
|
12
|
+
values either. The result is a real gap: nothing enforced that an enum-
|
|
13
|
+
constrained value stayed inside its enum. Every shipped agent carried
|
|
14
|
+
``permissionMode: "ask"`` for an extended period even though ``ask`` is not in
|
|
15
|
+
the schema's ``permissionMode`` enum
|
|
16
|
+
(``["default", "acceptEdits", "auto", "dontAsk", "bypassPermissions", "plan"]``,
|
|
17
|
+
mirroring the Claude Code vendor canon) — the drift went undetected because no
|
|
18
|
+
gate enforced enum values. This validator closes that gap.
|
|
19
|
+
|
|
20
|
+
What it checks. For each governed artifact class it loads the class's JSON
|
|
21
|
+
Schema from the ``schemas/`` sibling and, for every property that declares a
|
|
22
|
+
value constraint — an ``enum`` and/or a ``pattern``, directly or inside a
|
|
23
|
+
``oneOf`` / ``anyOf`` branch — validates that the artifact's frontmatter value
|
|
24
|
+
satisfies the constraint. The governed classes and their schemas:
|
|
25
|
+
|
|
26
|
+
- ``agents`` → ``agent.schema.json`` (enums: ``permissionMode``, ``effort``,
|
|
27
|
+
``isolation``, ``color``, and the ``memory`` ``oneOf`` string-enum/boolean;
|
|
28
|
+
patterns: ``name``, ``version``, ``updated``).
|
|
29
|
+
- ``commands`` → ``command.schema.json`` (patterns: ``name``, ``version``,
|
|
30
|
+
``updated``). ``additionalProperties: false``, but key/required validation is
|
|
31
|
+
owned by ``frontmatter_grep`` and the doc-example test — this validator adds
|
|
32
|
+
the value-level pattern enforcement those surfaces lack.
|
|
33
|
+
- ``skills`` → ``skill.schema.json`` (enum: ``effort``; patterns: ``name``,
|
|
34
|
+
``version``, ``updated``, ``archetype``).
|
|
35
|
+
|
|
36
|
+
Scope boundary. This validator is value-only and schema-driven: it never
|
|
37
|
+
hardcodes a field list (a new enum/pattern property added to a schema is picked
|
|
38
|
+
up automatically), and it raises no finding for a *missing* key or an *absent*
|
|
39
|
+
frontmatter block — presence is owned by ``frontmatter_grep``. Type / required /
|
|
40
|
+
``additionalProperties`` / ``maxLength`` enforcement are deliberately out of
|
|
41
|
+
scope here; only ``enum`` and ``pattern`` value constraints are checked, which is
|
|
42
|
+
exactly the class of drift the documented gap names. A frontmatter block that
|
|
43
|
+
does not parse as a YAML mapping is skipped (its parse failure is a
|
|
44
|
+
``frontmatter_grep`` concern), so every finding this validator emits is an
|
|
45
|
+
enum/pattern value violation a fix can clear.
|
|
46
|
+
|
|
47
|
+
Detection. For each class, glob the corpus under ``root`` (``src/apothem/
|
|
48
|
+
agents/*.md``, ``src/apothem/commands/*.md``, ``src/apothem/skills/*/SKILL.md``),
|
|
49
|
+
extract the leading ``---``-delimited frontmatter block (tolerating an optional
|
|
50
|
+
leading HTML-comment banner per the sibling-convention), parse it with PyYAML,
|
|
51
|
+
and validate each constraint-bearing property present in the mapping.
|
|
52
|
+
|
|
53
|
+
Exit semantics. Exits 0 when every governed artifact's constrained values
|
|
54
|
+
satisfy their schema, OR when no governed artifact is present under ``root``
|
|
55
|
+
(an installed tree with no source cohort). Exits 2 on any enum/pattern value
|
|
56
|
+
violation. The exit-2 convention matches the conformity-gate orchestrator's
|
|
57
|
+
``EXIT_FAIL``; the gate runs this validator (blocking, like
|
|
58
|
+
``agent_capability_grep``) via subprocess in ``--all`` mode.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
from __future__ import annotations
|
|
62
|
+
|
|
63
|
+
import json
|
|
64
|
+
import re
|
|
65
|
+
import sys
|
|
66
|
+
from dataclasses import asdict, dataclass, field
|
|
67
|
+
from pathlib import Path
|
|
68
|
+
from typing import Any, Final
|
|
69
|
+
|
|
70
|
+
import yaml
|
|
71
|
+
|
|
72
|
+
GREP_NAME: Final[str] = "frontmatter-value-grep"
|
|
73
|
+
RULE_ANCHOR: Final[str] = "per-class JSON Schema enum/pattern value constraints"
|
|
74
|
+
|
|
75
|
+
EXIT_PASS: Final[int] = 0
|
|
76
|
+
EXIT_FAIL: Final[int] = 2
|
|
77
|
+
|
|
78
|
+
# Schema/data files ride beside the conformity package in both the repo
|
|
79
|
+
# checkout (``src/apothem/{conformity,schemas}``) and the installed tree
|
|
80
|
+
# (``<install-root>/apothem/{conformity,schemas}``). Resolve one parent hop
|
|
81
|
+
# above this module so the same code finds its schemas in both shapes — the
|
|
82
|
+
# dual-shape anchor convention shared with ``file_header_grep`` /
|
|
83
|
+
# ``reference_token_grep`` and asserted by
|
|
84
|
+
# ``tests/conformity/test_schema_anchor_resolution.py``.
|
|
85
|
+
SCHEMAS_DIR: Final[Path] = Path(__file__).resolve().parents[1] / "schemas"
|
|
86
|
+
|
|
87
|
+
FRONTMATTER_DELIMITER: Final[str] = "---"
|
|
88
|
+
|
|
89
|
+
# Governed artifact classes: (class, schema filename, corpus glob under root).
|
|
90
|
+
# Schema-driven — the constrained properties are read from each schema's
|
|
91
|
+
# ``properties`` block, never hardcoded here, so a new enum/pattern property
|
|
92
|
+
# added to a schema is enforced without editing this validator.
|
|
93
|
+
_COHORTS: Final[tuple[tuple[str, str, str], ...]] = (
|
|
94
|
+
("agents", "agent.schema.json", "src/apothem/agents/*.md"),
|
|
95
|
+
("commands", "command.schema.json", "src/apothem/commands/*.md"),
|
|
96
|
+
("skills", "skill.schema.json", "src/apothem/skills/*/SKILL.md"),
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
# JSON Schema ``type`` -> the Python type(s) a conforming value carries. Only
|
|
100
|
+
# the types that appear in the governed schemas need exact handling; ``integer``
|
|
101
|
+
# and ``boolean`` need the bool/int disambiguation Python's ``isinstance``
|
|
102
|
+
# otherwise blurs (``bool`` is a subclass of ``int``).
|
|
103
|
+
_JSON_SCALAR_TYPES: Final[frozenset[str]] = frozenset(
|
|
104
|
+
{"string", "boolean", "integer", "number", "array", "object", "null"}
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@dataclass(frozen=True)
|
|
109
|
+
class Finding:
|
|
110
|
+
"""One frontmatter value that violates its schema enum/pattern constraint."""
|
|
111
|
+
|
|
112
|
+
surface: str
|
|
113
|
+
artifact_class: str
|
|
114
|
+
key: str
|
|
115
|
+
detail: str
|
|
116
|
+
rule: str = RULE_ANCHOR
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
@dataclass(frozen=True)
|
|
120
|
+
class GrepResult:
|
|
121
|
+
"""Aggregated walk result for one corpus sweep."""
|
|
122
|
+
|
|
123
|
+
grep: str
|
|
124
|
+
root: str
|
|
125
|
+
files_inspected: int
|
|
126
|
+
passed: bool
|
|
127
|
+
informational: str | None = None
|
|
128
|
+
findings: list[Finding] = field(default_factory=list)
|
|
129
|
+
|
|
130
|
+
def to_json(self) -> str:
|
|
131
|
+
payload = {
|
|
132
|
+
"grep": self.grep,
|
|
133
|
+
"root": self.root,
|
|
134
|
+
"files_inspected": self.files_inspected,
|
|
135
|
+
"passed": self.passed,
|
|
136
|
+
"informational": self.informational,
|
|
137
|
+
"findings": [asdict(f) for f in self.findings],
|
|
138
|
+
}
|
|
139
|
+
return json.dumps(payload, indent=2)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def _extract_frontmatter(content: str) -> str | None:
|
|
143
|
+
"""Return the leading ``---``-delimited YAML block, or None when absent.
|
|
144
|
+
|
|
145
|
+
Mirrors the sibling-convention extractor: tolerate a leading region of
|
|
146
|
+
blank lines plus one optional HTML-comment banner before the opening
|
|
147
|
+
``---`` delimiter, then return the text between the opening and the next
|
|
148
|
+
``---`` line. The governed cohorts place frontmatter first; the optional
|
|
149
|
+
leading-comment tolerance keeps the extractor robust to the
|
|
150
|
+
banner-then-frontmatter ordering some surfaces use.
|
|
151
|
+
"""
|
|
152
|
+
lines = content.splitlines()
|
|
153
|
+
index = 0
|
|
154
|
+
|
|
155
|
+
while index < len(lines) and not lines[index].strip():
|
|
156
|
+
index += 1
|
|
157
|
+
|
|
158
|
+
if index < len(lines) and lines[index].lstrip().startswith("<!--"):
|
|
159
|
+
first = lines[index].strip()
|
|
160
|
+
if first.endswith("-->") and first != "<!--":
|
|
161
|
+
index += 1
|
|
162
|
+
else:
|
|
163
|
+
index += 1
|
|
164
|
+
while index < len(lines) and not lines[index].strip().endswith("-->"):
|
|
165
|
+
index += 1
|
|
166
|
+
if index < len(lines):
|
|
167
|
+
index += 1
|
|
168
|
+
|
|
169
|
+
while index < len(lines) and not lines[index].strip():
|
|
170
|
+
index += 1
|
|
171
|
+
|
|
172
|
+
if index >= len(lines) or lines[index].strip() != FRONTMATTER_DELIMITER:
|
|
173
|
+
return None
|
|
174
|
+
|
|
175
|
+
open_index = index
|
|
176
|
+
for close_index in range(open_index + 1, len(lines)):
|
|
177
|
+
if lines[close_index].strip() == FRONTMATTER_DELIMITER:
|
|
178
|
+
return "\n".join(lines[open_index + 1 : close_index])
|
|
179
|
+
return None
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def _branches(prop_schema: dict[str, Any]) -> list[dict[str, Any]]:
|
|
183
|
+
"""Return a property's alternative schemas: its ``oneOf`` / ``anyOf`` branch
|
|
184
|
+
list, or ``[prop_schema]`` when the property is a single un-branched schema.
|
|
185
|
+
A value is conforming when it satisfies at least one alternative."""
|
|
186
|
+
for combinator in ("oneOf", "anyOf"):
|
|
187
|
+
branches = prop_schema.get(combinator)
|
|
188
|
+
if isinstance(branches, list):
|
|
189
|
+
return [b for b in branches if isinstance(b, dict)]
|
|
190
|
+
return [prop_schema]
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def _carries_value_constraint(prop_schema: dict[str, Any]) -> bool:
|
|
194
|
+
"""True iff the property declares an ``enum`` or ``pattern`` in any branch."""
|
|
195
|
+
return any(
|
|
196
|
+
("enum" in branch or "pattern" in branch) for branch in _branches(prop_schema)
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def _type_matches(value: Any, json_type: str) -> bool: # noqa: ANN401 - duck-typed YAML scalar
|
|
201
|
+
"""True iff *value* satisfies the JSON Schema scalar ``type``.
|
|
202
|
+
|
|
203
|
+
Disambiguates ``bool`` from ``int``/``number`` (a Python ``bool`` is an
|
|
204
|
+
``int`` subclass, but JSON treats them as distinct types). Unknown types are
|
|
205
|
+
not constrained (return True) so a future schema type never fail-closes.
|
|
206
|
+
"""
|
|
207
|
+
if json_type not in _JSON_SCALAR_TYPES:
|
|
208
|
+
return True
|
|
209
|
+
if json_type == "boolean":
|
|
210
|
+
return isinstance(value, bool)
|
|
211
|
+
if json_type == "integer":
|
|
212
|
+
return isinstance(value, int) and not isinstance(value, bool)
|
|
213
|
+
if json_type == "number":
|
|
214
|
+
return isinstance(value, (int, float)) and not isinstance(value, bool)
|
|
215
|
+
if json_type == "string":
|
|
216
|
+
return isinstance(value, str)
|
|
217
|
+
if json_type == "array":
|
|
218
|
+
return isinstance(value, list)
|
|
219
|
+
if json_type == "object":
|
|
220
|
+
return isinstance(value, dict)
|
|
221
|
+
return value is None # "null"
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def _branch_accepts(value: Any, branch: dict[str, Any]) -> bool: # noqa: ANN401 - duck-typed YAML scalar
|
|
225
|
+
"""True iff *value* satisfies one branch's type + enum + pattern constraints."""
|
|
226
|
+
json_type = branch.get("type")
|
|
227
|
+
if isinstance(json_type, str) and not _type_matches(value, json_type):
|
|
228
|
+
return False
|
|
229
|
+
enum = branch.get("enum")
|
|
230
|
+
if isinstance(enum, list) and value not in enum:
|
|
231
|
+
return False
|
|
232
|
+
pattern = branch.get("pattern")
|
|
233
|
+
# JSON Schema ``pattern`` is an unanchored search; the governed schemas all
|
|
234
|
+
# carry their own ``^...$`` anchors, so search == full match here.
|
|
235
|
+
if isinstance(pattern, str):
|
|
236
|
+
return isinstance(value, str) and re.search(pattern, value) is not None
|
|
237
|
+
return True
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def _value_valid(value: Any, prop_schema: dict[str, Any]) -> bool: # noqa: ANN401 - duck-typed YAML scalar
|
|
241
|
+
"""True iff *value* satisfies at least one of the property's alternatives."""
|
|
242
|
+
return any(_branch_accepts(value, branch) for branch in _branches(prop_schema))
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def _expected_summary(prop_schema: dict[str, Any]) -> str:
|
|
246
|
+
"""Human-readable summary of a property's accepted forms, for the finding."""
|
|
247
|
+
parts: list[str] = []
|
|
248
|
+
for branch in _branches(prop_schema):
|
|
249
|
+
enum = branch.get("enum")
|
|
250
|
+
pattern = branch.get("pattern")
|
|
251
|
+
if isinstance(enum, list):
|
|
252
|
+
parts.append("one of " + ", ".join(repr(v) for v in enum))
|
|
253
|
+
if isinstance(pattern, str):
|
|
254
|
+
parts.append(f"a string matching /{pattern}/")
|
|
255
|
+
if enum is None and pattern is None and isinstance(branch.get("type"), str):
|
|
256
|
+
parts.append(f"a {branch['type']}")
|
|
257
|
+
return " or ".join(parts) if parts else "a schema-conformant value"
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def _load_value_constraints(schema_path: Path) -> dict[str, dict[str, Any]]:
|
|
261
|
+
"""Return ``{property: schema}`` for every constraint-bearing property.
|
|
262
|
+
|
|
263
|
+
A missing or unparseable schema yields an empty constraint map (the cohort
|
|
264
|
+
is then skipped with no findings) rather than fail-closing the whole sweep.
|
|
265
|
+
"""
|
|
266
|
+
try:
|
|
267
|
+
raw = schema_path.read_text(encoding="utf-8")
|
|
268
|
+
except OSError:
|
|
269
|
+
return {}
|
|
270
|
+
try:
|
|
271
|
+
schema = json.loads(raw)
|
|
272
|
+
except json.JSONDecodeError:
|
|
273
|
+
return {}
|
|
274
|
+
properties = schema.get("properties") if isinstance(schema, dict) else None
|
|
275
|
+
if not isinstance(properties, dict):
|
|
276
|
+
return {}
|
|
277
|
+
return {
|
|
278
|
+
name: prop
|
|
279
|
+
for name, prop in properties.items()
|
|
280
|
+
if isinstance(prop, dict) and _carries_value_constraint(prop)
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def _check_file(
|
|
285
|
+
path: Path,
|
|
286
|
+
root: Path,
|
|
287
|
+
artifact_class: str,
|
|
288
|
+
constraints: dict[str, dict[str, Any]],
|
|
289
|
+
) -> tuple[bool, list[Finding]]:
|
|
290
|
+
"""Validate one artifact file's constrained frontmatter values.
|
|
291
|
+
|
|
292
|
+
Returns ``(inspected, findings)``: ``inspected`` is True when the file
|
|
293
|
+
carried a parseable frontmatter mapping (and was therefore value-checked).
|
|
294
|
+
A file with no frontmatter block, or a block that does not parse to a
|
|
295
|
+
mapping, is not inspected and contributes no findings — presence and parse
|
|
296
|
+
integrity are owned by ``frontmatter_grep``.
|
|
297
|
+
"""
|
|
298
|
+
try:
|
|
299
|
+
content = path.read_text(encoding="utf-8")
|
|
300
|
+
except (OSError, UnicodeDecodeError):
|
|
301
|
+
return False, []
|
|
302
|
+
block = _extract_frontmatter(content)
|
|
303
|
+
if block is None:
|
|
304
|
+
return False, []
|
|
305
|
+
try:
|
|
306
|
+
parsed = yaml.safe_load(block)
|
|
307
|
+
except yaml.YAMLError:
|
|
308
|
+
return False, []
|
|
309
|
+
if not isinstance(parsed, dict):
|
|
310
|
+
return False, []
|
|
311
|
+
|
|
312
|
+
try:
|
|
313
|
+
surface = str(path.relative_to(root))
|
|
314
|
+
except ValueError:
|
|
315
|
+
surface = str(path)
|
|
316
|
+
|
|
317
|
+
findings: list[Finding] = []
|
|
318
|
+
for key, prop_schema in constraints.items():
|
|
319
|
+
if key not in parsed:
|
|
320
|
+
continue
|
|
321
|
+
value = parsed[key]
|
|
322
|
+
if _value_valid(value, prop_schema):
|
|
323
|
+
continue
|
|
324
|
+
findings.append(
|
|
325
|
+
Finding(
|
|
326
|
+
surface=surface,
|
|
327
|
+
artifact_class=artifact_class,
|
|
328
|
+
key=key,
|
|
329
|
+
detail=(
|
|
330
|
+
f"{key!r} value {value!r} violates the {artifact_class} schema: "
|
|
331
|
+
f"expected {_expected_summary(prop_schema)}"
|
|
332
|
+
),
|
|
333
|
+
)
|
|
334
|
+
)
|
|
335
|
+
return True, findings
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def check(root: Path) -> GrepResult:
|
|
339
|
+
"""Walk every governed cohort under *root*; flag enum/pattern value violations."""
|
|
340
|
+
findings: list[Finding] = []
|
|
341
|
+
files_inspected = 0
|
|
342
|
+
for artifact_class, schema_filename, glob_pattern in _COHORTS:
|
|
343
|
+
constraints = _load_value_constraints(SCHEMAS_DIR / schema_filename)
|
|
344
|
+
if not constraints:
|
|
345
|
+
continue
|
|
346
|
+
for path in sorted(root.glob(glob_pattern)):
|
|
347
|
+
if not path.is_file():
|
|
348
|
+
continue
|
|
349
|
+
inspected, file_findings = _check_file(
|
|
350
|
+
path, root, artifact_class, constraints
|
|
351
|
+
)
|
|
352
|
+
if inspected:
|
|
353
|
+
files_inspected += 1
|
|
354
|
+
findings.extend(file_findings)
|
|
355
|
+
|
|
356
|
+
informational: str | None = None
|
|
357
|
+
if files_inspected == 0:
|
|
358
|
+
informational = (
|
|
359
|
+
"no governed artifact (agent / command / skill) carrying frontmatter "
|
|
360
|
+
f"found under {root}; validator is in an absence-tolerant pass"
|
|
361
|
+
)
|
|
362
|
+
return GrepResult(
|
|
363
|
+
grep=GREP_NAME,
|
|
364
|
+
root=str(root),
|
|
365
|
+
files_inspected=files_inspected,
|
|
366
|
+
passed=not findings,
|
|
367
|
+
informational=informational,
|
|
368
|
+
findings=findings,
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
def _read_input(argv: list[str]) -> Path:
|
|
373
|
+
if len(argv) >= 2:
|
|
374
|
+
return Path(argv[1])
|
|
375
|
+
return Path.cwd()
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
def _main(argv: list[str]) -> int:
|
|
379
|
+
root = _read_input(argv)
|
|
380
|
+
result = check(root)
|
|
381
|
+
print(result.to_json())
|
|
382
|
+
return EXIT_PASS if result.passed else EXIT_FAIL
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
if __name__ == "__main__":
|
|
386
|
+
sys.exit(_main(sys.argv))
|