From a5bcc1a5916105a9fc8d5f3118bd1e7f291e8d57 Mon Sep 17 00:00:00 2001 From: Justin Diclemente Date: Fri, 19 Jun 2026 19:07:52 -0400 Subject: [PATCH 1/3] fix: honor managed scope in config env bridges --- dag_cli/main.py | 12 +++++++++++- dag_cli/send_cmd.py | 8 ++++++++ gateway/run.py | 20 ++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/dag_cli/main.py b/dag_cli/main.py index d3302e0..d1ecec0 100644 --- a/dag_cli/main.py +++ b/dag_cli/main.py @@ -531,7 +531,17 @@ def _resolve_sudo_user_profile_env(name: str) -> str | None: if _cfg_path.exists(): with open(_cfg_path, encoding="utf-8") as _f: _early_cfg_raw = _yaml_early.safe_load(_f) or {} - if "DAG_REDACT_SECRETS" not in os.environ: + # Managed scope: overlay administrator-pinned values so a managed + # security.redact_secrets / network.force_ipv4 wins here too. This early + # bridge reads config.yaml directly (before load_config is usable), so + # without the overlay a managed redact_secrets toggle would be ignored. + # Fail-open via the shared helper. + try: + from hermes_cli import managed_scope + _early_cfg_raw = managed_scope.apply_managed_overlay(_early_cfg_raw) + except Exception: + pass + if "DAG_REDACT_SECRETS" not in os.environ and "HERMES_REDACT_SECRETS" not in os.environ: _early_sec_cfg = _early_cfg_raw.get("security", {}) if isinstance(_early_sec_cfg, dict): _early_redact = _early_sec_cfg.get("redact_secrets") diff --git a/dag_cli/send_cmd.py b/dag_cli/send_cmd.py index d502ac2..ea7bbe2 100644 --- a/dag_cli/send_cmd.py +++ b/dag_cli/send_cmd.py @@ -276,6 +276,14 @@ def _load_dag_env() -> None: except Exception: pass + # Managed scope: overlay administrator-pinned values before bridging to env, + # so a managed top-level scalar wins here too. Fail-open via the helper. + try: + from hermes_cli import managed_scope + raw = managed_scope.apply_managed_overlay(raw if isinstance(raw, dict) else {}) + except Exception: + pass + if not isinstance(raw, dict): return diff --git a/gateway/run.py b/gateway/run.py index d539306..9d0c8c8 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -1104,6 +1104,15 @@ def _reload_runtime_env_preserving_config_authority() -> None: cfg = _yaml.safe_load(f) or {} from dag_cli.config import _expand_env_vars cfg = _expand_env_vars(cfg) + # Managed scope: keep administrator-pinned values authoritative on every + # turn too. This per-turn reload re-bridges config→env, so without the + # overlay a managed agent.max_turns / timezone / redact_secrets would be + # replaced by the user's value after the first turn. Fail-open. + try: + from hermes_cli import managed_scope + cfg = managed_scope.apply_managed_overlay(cfg) + except Exception: + pass except Exception: return @@ -1126,6 +1135,17 @@ def _reload_runtime_env_preserving_config_authority() -> None: # Expand ${ENV_VAR} references before bridging to env vars. from dag_cli.config import _expand_env_vars _cfg = _expand_env_vars(_cfg) + # Managed scope: overlay administrator-pinned values BEFORE bridging to + # env vars, so a managed timezone / redact_secrets / max_turns / terminal + # setting wins over the user's value at the env layer too. This bridge + # reads config.yaml directly (not via load_config), so without the + # overlay every HERMES_*/TERMINAL_* env var below would carry the user's + # value even when an administrator pinned it. Fail-open via the helper. + try: + from hermes_cli import managed_scope + _cfg = managed_scope.apply_managed_overlay(_cfg) + except Exception: + pass # Top-level simple values (fallback only — don't override .env) for _key, _val in _cfg.items(): if isinstance(_val, (str, int, float, bool)) and _key not in os.environ: From 99aa74f4418ea6eafafc8b9a3978b3fdf7c5fab1 Mon Sep 17 00:00:00 2001 From: Justin Diclemente Date: Fri, 19 Jun 2026 19:10:46 -0400 Subject: [PATCH 2/3] docs: add lean agentic pr template system --- .github/pull_request_template.md | 39 +++++++++++++++++ README.md | 11 +++++ .../templates/pr-body-bugfix.md | 31 +++++++------ .../templates/pr-body-feature.md | 43 +++++++++++-------- 4 files changed, 94 insertions(+), 30 deletions(-) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..8a59dc9 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,39 @@ +## Summary + +- + +## Why this change + +- What problem does this solve? +- Why is this the right fix for Collar's DAG-first system? + +## DAG / spec impact + +- [ ] No new skill unless required +- [ ] Uses existing `.dag`/dotdog systems +- [ ] Keeps token overhead low +- [ ] Updates existing behavior rather than adding new layers + +If any box is unchecked, explain why. + +## Changes + +- + +## Reasoning + +- Why these changes, and why this scope? +- What upstream change, bug, or user need drove it? +- What was intentionally left out to avoid bloat? + +## Test plan + +- [ ] Unit tests +- [ ] Manual verification +- [ ] No regression in existing behavior + +## Risk + +- Impact: +- Rollback: +- Notes: diff --git a/README.md b/README.md index 02fbbb9..db70f22 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,17 @@ collar setup # first-time setup wizard - [dotdog](https://github.com/specdog/dotdog) — `.dog` spec format + compiler - [specdog](https://github.com/specdog) — the org +- PRs use an agentic template: `.github/pull_request_template.md` + +## PR system + +Collar PRs should stay lean and agentic: + +- start from the PR template +- explain the reasoning, not just the diff +- prefer updating existing systems over adding new ones +- keep `.dag` as the first-read source for agent behavior +- avoid adding skills or layers that inflate token use unless the change clearly needs them ## Dogfood diff --git a/skills/github/github-pr-workflow/templates/pr-body-bugfix.md b/skills/github/github-pr-workflow/templates/pr-body-bugfix.md index c80f220..c8fd32c 100644 --- a/skills/github/github-pr-workflow/templates/pr-body-bugfix.md +++ b/skills/github/github-pr-workflow/templates/pr-body-bugfix.md @@ -1,22 +1,29 @@ ## Bug Description - - -Fixes # +- ## Root Cause - +- ## Fix - +- -- +## Why this fix -## How to Verify +- Why this approach? +- Why this scope? +- Why not a larger refactor? + +## DAG / spec impact - +- [ ] Uses existing `.dag` / dotdog systems +- [ ] No new skill unless required +- [ ] Keeps token overhead low +- [ ] Updates existing behavior instead of adding layers + +## How to Verify 1. 2. @@ -24,12 +31,12 @@ Fixes # ## Test Plan -- [ ] Added regression test for this bug +- [ ] Added regression test - [ ] Existing tests still pass - [ ] Manual verification of the fix ## Risk Assessment - - -Low / Medium / High — +- Impact: +- Rollback: +- Notes: diff --git a/skills/github/github-pr-workflow/templates/pr-body-feature.md b/skills/github/github-pr-workflow/templates/pr-body-feature.md index 495aa16..0ca0f37 100644 --- a/skills/github/github-pr-workflow/templates/pr-body-feature.md +++ b/skills/github/github-pr-workflow/templates/pr-body-feature.md @@ -1,33 +1,40 @@ ## Summary - +- -- +## Why this change -## Motivation +- Why now? +- What user or upstream need does it address? +- Why this scope and not more? - +## DAG / spec impact -Closes # +- [ ] Uses existing `.dag` / dotdog systems +- [ ] No new skill unless required +- [ ] Keeps token overhead low +- [ ] Updates existing behavior instead of adding layers -## Changes +If any box is unchecked, explain why. - +## Changes -- +- -## Test Plan +## Reasoning - +- What was the design choice? +- What alternative was rejected? +- What did you intentionally leave out to keep Collar lean? -- [ ] Unit tests pass (`pytest`) -- [ ] Manual testing of new functionality -- [ ] No regressions in existing behavior - -## Screenshots / Examples +## Test Plan - +- [ ] Unit tests pass +- [ ] Manual verification completed +- [ ] No regression in existing behavior -## Notes for Reviewers +## Risk - +- Impact: +- Rollback: +- Notes: From 62cedddb906808eef00e0bb65fbb81f1fbb4341a Mon Sep 17 00:00:00 2001 From: Justin Diclemente Date: Fri, 19 Jun 2026 19:20:37 -0400 Subject: [PATCH 3/3] docs: add open source governance defaults --- .github/CODEOWNERS | 2 ++ .github/ISSUE_TEMPLATE/bug_report.md | 26 ++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 18 ++++++++++ .github/pull_request_template.md | 44 +++++------------------ CONTRIBUTING.md | 10 +++--- README.md | 9 ++++- SECURITY.md | 25 +++++++++++++ 7 files changed, 93 insertions(+), 41 deletions(-) create mode 100644 .github/CODEOWNERS create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 SECURITY.md diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..24a8348 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,2 @@ +# Default review ownership for Collar +* @logohere diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..45c66c4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,26 @@ +--- +name: Bug report +about: Report a reproducible bug +labels: bug +--- + +## What happened? + +## Expected behavior + +## Reproduction steps + +1. +2. +3. + +## Environment + +- Collar version: +- OS: +- Branch/commit: + +## Notes + +- Keep reports focused and reproducible. +- If this touches agent behavior, mention the relevant `.dag` path. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..de2cbb9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,18 @@ +--- +name: Feature request +about: Propose a small, focused improvement +labels: enhancement +--- + +## What problem are you solving? + +## Proposed change + +## Why this scope? + +## Alternatives considered + +## Notes + +- Prefer updating existing systems over adding new layers. +- If this affects agent behavior, include the `.dag` path involved. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 8a59dc9..cd4a804 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,39 +1,11 @@ -## Summary +# Pull request template -- +PRs must use the repo template: -## Why this change +- `.github/pull_request_template.md` -- What problem does this solve? -- Why is this the right fix for Collar's DAG-first system? - -## DAG / spec impact - -- [ ] No new skill unless required -- [ ] Uses existing `.dag`/dotdog systems -- [ ] Keeps token overhead low -- [ ] Updates existing behavior rather than adding new layers - -If any box is unchecked, explain why. - -## Changes - -- - -## Reasoning - -- Why these changes, and why this scope? -- What upstream change, bug, or user need drove it? -- What was intentionally left out to avoid bloat? - -## Test plan - -- [ ] Unit tests -- [ ] Manual verification -- [ ] No regression in existing behavior - -## Risk - -- Impact: -- Rollback: -- Notes: +Keep it lean: +- explain why the change exists +- note `.dag` / dotdog impact +- show tests or verification +- call out any intentional scope cuts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b6f5843..ea45abd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,10 +4,12 @@ DAG-first. `Entity→Target:verb(card)`. ## Rules -1. **NEVER read `.dog`** — agents query `.dag` via the router -2. **DAG-path notation** — all behavioral guidance in compact format -3. **Compile before commit** — run `dag-regen.sh --all` after any `.md`/`.dog` change -4. **Test harness fallback** — simulate fresh install, verify constants load from `dags/` +1. **Query `.dag` first** — agent behavior comes from `.dag` routes, not prose +2. **Keep dotdog in the loop** — compile/spec changes through the dotdog path +3. **Use the PR template** — every PR should use `.github/pull_request_template.md` +4. **DAG-path notation** — all behavioral guidance in compact format +5. **Compile before commit** — run `dag-regen.sh --all` after any `.md`/`.dog` change +6. **Test harness fallback** — simulate fresh install, verify constants load from `dags/` ## Project Structure diff --git a/README.md b/README.md index db70f22..1aaa419 100644 --- a/README.md +++ b/README.md @@ -94,11 +94,18 @@ collar setup # first-time setup wizard Collar PRs should stay lean and agentic: -- start from the PR template +- use `.github/pull_request_template.md` - explain the reasoning, not just the diff - prefer updating existing systems over adding new ones - keep `.dag` as the first-read source for agent behavior - avoid adding skills or layers that inflate token use unless the change clearly needs them +- include tests or verification for behavior changes + +## Governance + +- Branch protection on `main` requires PR review and a passing check +- Security issues should go through `SECURITY.md` +- Bugs and features have issue templates in `.github/ISSUE_TEMPLATE/` ## Dogfood diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..3fb13ce --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,25 @@ +# Security Policy + +## Supported Versions + +Security fixes land on the default branch and current release line. + +## Reporting a Vulnerability + +Do not open a public issue for security bugs. + +Use one of these instead: +- GitHub Security Advisory for this repository +- Direct contact with the maintainers through the private security channel + +Include: +- affected version or commit +- impact +- reproduction steps +- any suggested mitigation + +## Review Expectations + +- prefer minimal, targeted fixes +- avoid adding new systems unless the fix requires them +- keep `.dag`/dotdog paths lean when changing agent behavior