Skip to content

Adding Microsoft SECURITY.MD - #2

Closed
microsoft-github-policy-service[bot] wants to merge 2 commits into
mainfrom
users/GitHubPolicyService/7c4717f0-6164-4d13-bbab-62acc088a089
Closed

Adding Microsoft SECURITY.MD#2
microsoft-github-policy-service[bot] wants to merge 2 commits into
mainfrom
users/GitHubPolicyService/7c4717f0-6164-4d13-bbab-62acc088a089

Conversation

@microsoft-github-policy-service

Copy link
Copy Markdown

Please accept this contribution adding the standard Microsoft SECURITY.MD 🔒 file to help the community understand the security policy and how to safely report security issues. GitHub uses the presence of this file to light-up security reminders and a link to the file. This pull request commits the latest official SECURITY.MD file from https://github.com/microsoft/repo-templates/blob/main/shared/SECURITY.md.

Microsoft teams can learn more about this effort and share feedback within the open source guidance available internally.

jakepresent pushed a commit that referenced this pull request May 1, 2026
@jakepresent jakepresent closed this May 1, 2026
AaronAspinwall123 added a commit that referenced this pull request May 8, 2026
Five issues raised in the Copilot Code Review and confirmed by manual
inspection. All 560 Python tests pass (+9 new) and viewer `npm run check`
reports 0 errors / 0 warnings.

#1 (security, viewer/src/lib/server/artifacts.ts): manifestRelativePath
now filters out '..' parts and manifestArtifactPath returns null when the
path would escape the suite directory; runSeedRows already falls back to
the legacy seeds.jsonl in that case.

#2 (bug, viewer/src/lib/server/artifacts.ts): listRunIds now also
filters entries through isSafeArtifactId so the run list cannot include
names that requireSafeId would later reject with a 500.

#3 (critical, p2m/runner.py + p2m/core/artifact_cache.py): when
artifact caching is active, the runner now overrides save_dir/save_path
in raw_cfg via override_cacheable_output_paths so user YAML cannot
redirect cacheable stage outputs outside the versioned artifact dir.
finalize_artifact_plan would otherwise fail to find the outputs.

#4 (security, p2m/viewer_read_model.py): _manifest_relative_path now
rejects '..' segments and returns None; _seed_artifact_path falls back
to suite_dir/seeds.jsonl when the helper rejects the manifest path.

#5 (operational, p2m/core/artifact_cache.py): _load_json_object now
catches json.JSONDecodeError and OSError, prints a stderr warning, and
returns None so a corrupt latest.json/artifact.json degrades to a cache
miss instead of aborting the pipeline. _resolve_ref_path also rejects
'..' segments as defense in depth.

New tests:
- test_artifact_cache.py: corrupt JSON gracefully ignored, non-object
  payload rejected, _resolve_ref_path traversal rejection,
  override_cacheable_output_paths for policy save_dir, seeds save_path,
  and unknown stage no-op.
- test_runner_artifact_cache.py: end-to-end test that user-supplied
  save_dir/save_path in raw_cfg is overridden so artifacts still land
  in the versioned cache directory.
- test_viewer_server_artifacts.py: _manifest_relative_path traversal
  rejection (in both the existing TS-gated class and a new always-run
  ViewerReadModelHelpersTest class) and _seed_artifact_path fallback
  on malicious manifests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
AaronAspinwall123 added a commit that referenced this pull request May 8, 2026
Four follow-up issues raised by Copilot on commit cc96e06. All 561 Python
tests pass (+1 net new) and viewer `npm run check` reports 0 errors / 0
warnings.

#1 (moderate, bug, p2m/core/artifact_cache.py): activate_latest_artifacts
now detects whether the artifact_dir or metadata_path in latest.json was
stale (resolved path missing) and, when it is, rebuilds the ref via
_ref_from_metadata using the on-disk paths and persists the corrected ref
through update_latest. Without this, ctx and downstream run manifests
silently propagated paths that no longer exist.

#2 (critical, security, viewer/src/lib/server/artifacts.ts):
manifestArtifactPath now refuses absolute paths from manifest.json (with a
console warning) and returns null, so runSeedRows falls back to the legacy
seeds.jsonl. Without this, an absolute path bypassed the relative '..'
defense.

#3 (critical, security, p2m/viewer_read_model.py): _seed_artifact_path
now refuses absolute paths from manifest.json (with a stderr warning) and
falls back to suite_dir/seeds.jsonl, matching the TS fix.

#4 (moderate, maintainability, tests/test_viewer_server_artifacts.py):
removed the duplicated _seed_artifact_path traversal test from the
TS-gated ViewerServerArtifactsTest; the always-run
ViewerReadModelHelpersTest is the single home for these helper assertions
and now also covers the absolute-path defense.

New test:
- tests/test_artifact_cache.py:
  test_activate_latest_rebuilds_ref_when_recorded_paths_are_stale -
  regression for #1; mutates latest.json to point at MISSING paths
  and asserts both ctx and the persisted latest.json are updated to the
  on-disk version directory.
- tests/test_viewer_server_artifacts.py:
  ViewerReadModelHelpersTest.test_seed_artifact_path_rejects_absolute_paths -
  regression for #3.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
AaronAspinwall123 added a commit that referenced this pull request May 8, 2026
… a directory

Two follow-up Copilot comments on commit a9115ad. Both identify a real
edge case I introduced in round 2 when `_manifest_relative_path` /
`manifestRelativePath` started returning `base_dir` for normalized-empty
parts. A manifest path of `"."`, `"./"`, or `"/."` would resolve to
the suite directory itself, then the JSONL reader would EISDIR.

#1 (moderate, security, viewer/src/lib/server/artifacts.ts):
manifestRelativePath now rejects paths that normalize to no segments and
returns null, so runSeedRows falls back to the legacy seeds.jsonl.

#2 (moderate, security, p2m/viewer_read_model.py): same fix in Python;
_manifest_relative_path returns None for normalized-empty paths and
_seed_artifact_path falls back to suite_dir/seeds.jsonl.

New test:
- tests/test_viewer_server_artifacts.py:
  ViewerReadModelHelpersTest.test_seed_artifact_path_rejects_paths_that_normalize_to_directory
  exercises `"."`, `"./"`, `"/."`, `"./."`, `"././"` and asserts
  both _manifest_relative_path returns None and _seed_artifact_path falls
  back to suite_dir/seeds.jsonl.

Validation: 562 passed (+1 new), 14 skipped; viewer npm run check 0 errors
/ 0 warnings.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
AaronAspinwall123 added a commit that referenced this pull request May 8, 2026
…user save_dir override

Addresses Jake's review on the artifact-cache PR.

1. Disk-leak on stage failure (Jake's #2): when a cacheable suite stage failed after prepare_artifact_plan allocated vNNNN/ but before finalize_artifact_plan wrote the sidecar, the partial directory stayed on disk forever. _next_version kept incrementing past abandoned slots and the stage_root accumulated dead version directories on every failed run. Adds discard_artifact_plan(ctx, plan) to remove the version directory and pop the orphaned ctx['artifact_versions'] entry. Wired into runner.py's stage exception path. No-ops for reused plans so a downstream failure cannot blow away a healthy upstream cache hit. latest.json is left untouched (finalize is its only writer for non-reused plans, so a discarded plan never touched it).

2. Silent override of user save_dir (Jake's non-blocking #2): override_cacheable_output_paths now log.warnings whenever it replaces a user-supplied save_dir/save_path with the versioned cache location. Customers who set save_dir in YAML get a clear actionable message instead of seeing their value silently ignored. No warning when no user value was set.

3. Concept-hash transitive flow (Jake's non-blocking #1): added a comment in _stage_descriptor explaining that concept_hash is computed only for policy and propagates through the dependency chain to design and seeds via _dependency_descriptor. Notes the safety invariant (every cacheable stage must depend on its upstream) so a future stage that breaks the chain triggers a code-review flag rather than silent stale-cache reads after a concept edit.

Note: Copilot findings on _metadata_outputs_exist / _metadata_output_paths primary-key KeyError and basename validation (Jake's #1) were already addressed in de9a32a (round 4) — _metadata_output_paths now overlays metadata onto the canonical _output_paths default keyset and _metadata_outputs_exist verifies every expected file exists on disk via the merged path map. _is_safe_artifact_basename rejects unsafe filenames before they become Path components.

Tests: +7 regression tests (4 for discard helper covering missing dir, reused plan, ctx cleanup, version-slot reuse; 2 for override warning behavior; 1 runner integration test that fails design mid-stage and asserts vNNNN is cleaned up plus next run reuses the freed slot).

Verified: 585 passed, 14 skipped (2 pre-existing Windows logging tempdir flakes from main's PR #22 deselected). npm --prefix viewer run check: 0 errors / 0 warnings.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
changliu2 added a commit that referenced this pull request Jun 8, 2026
…de conflicts (Jake's PR #230 re-review)

Fix two source-of-truth conflicts Jake flagged on 2026-06-08:

1. 72h escalation was effectively a third write exception (polite ping comment) on top of the two narrow writes. Collapsed into the existing narrow write #2: at 72h, request review from a second CODEOWNER on the same path. GitHub's review-request mechanism notifies the new reviewer directly; no separate ping comment needed. Aligned: AGENTS.md (escalation table) + dev-maintainer.md (escalation table + workflow bullet).

2. Designer observation mode was internally inconsistent. AGENTS.md + designer.md said the designer observes and logs to designer-inbox; docs/agents/README.md said the inbox stays empty until activation. Single model now: designer has no schedule by default, so no observation runs. When the maintainer adds a schedule, the designer logs to designer-inbox. External writes (issue files, docs PRs) require separate explicit activation. Aligned: AGENTS.md (Default state + Public-safe inboxes + Designer stays observation-only), designer.md (trigger conditions), docs/agents/README.md (inbox bullet + trailing note).

Non-blocking #3: viewer/ does exist on this branch and on main (verified with git ls-tree). No change needed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
changliu2 added a commit that referenced this pull request Jun 9, 2026
#230)

* chore: add autonomous agent infra with vacation-mode governance

Adds a 5-agent observation-only system that maintains the ASSERT repo
during operator absence. Layer 2/3 governance baked in: narrow write
exceptions for the dev-maintainer agent (audit comments + co-owner
pings), 24h escalation rule, vacation calendar for routing exclusions.

Default state is VACATION MODE: all 5 agents are observation-only with
one exception — dev-maintainer may (a) post audit-only comments and
(b) request reviews from existing CODEOWNERS. It cannot approve, merge,
label, or close anything. All other agents (designer, feedback, pm,
comms) stay strictly observation-only.

Files:
- AGENTS.md: new `Autonomous agent system` section
- .github/agents/: 5 agent specs
- .github/skills/: 7 reusable skill specs
- .github/CODEOWNERS-VACATIONS.md: new calendar
- docs/agents/: README + 4 empty inbox templates

PM and comms inboxes are operator-internal and not in this repo.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs: resolve vacation-mode write-authority contradictions (Jake's PR #230 review)

Jake correctly flagged that the write-authority rules contradicted each
other across AGENTS.md, .github/agents/dev-maintainer.md, docs/agents/README.md,
and the PR body. Per the maintainer-agreed governance model (option b):
the dev-maintainer's two narrow writes (audit-only PR comment + reviewer
request per the 24h escalation rule) are active on merge; the other four
agents stay strictly observation-only.

Changes:
- AGENTS.md: replace "all five agents observation-only" with explicit
  "four of five; dev-maintainer has narrow exceptions active by default."
  Clarify that "activation" applies only to NEW write capabilities beyond
  the two narrow exceptions.
- .github/agents/dev-maintainer.md: rename "Activation gate" to
  "Activation gate (broader writes only)." Explicitly state the gate does
  not apply to the two narrow vacation-mode writes (those are active by
  default), only to potential future broader writes (approve, merge, label).
- docs/agents/README.md: rewrite the VACATION MODE section to call out
  the dev-maintainer exception in the same bulleted list as the
  prohibitions. Update the "Public-safe inboxes" section to flag that
  dev-inbox.md begins receiving rows post-merge while designer/feedback
  inboxes stay empty until those agents are activated.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs: resolve two lingering write-authority wording conflicts (Jake's PR #230 re-review)

Jake's second pass caught two spots that still implied the two narrow
writes were not yet active:

1. AGENTS.md "Public-safe inboxes" section said all three inboxes
   "remain empty until activation" — contradicts dev-inbox.md beginning
   to receive observation rows post-merge.

   Fix: per-inbox bullets that distinguish dev-inbox (active loop) from
   designer-inbox and feedback-inbox (templates until activation).

2. .github/agents/dev-maintainer.md "Sole human approver" listed
   "PR comments" as one of the writes requiring future approval — but
   audit-only PR comments are one of the two already-granted narrow
   writes.

   Fix: split into "already granted" vs "broader writes" explicitly.
   Broader list expanded to approving review, request-changes review,
   merge, label change, status check creation, issue filing, Discussion
   reply — so it's unambiguous what's gated.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Bifurcate agent system: move operator-only specs out of public repo

Boundary-rule audit: the original PR exposed four operator-only surfaces
that don't belong in a public Microsoft-affiliated repo:

  1. .github/CODEOWNERS-VACATIONS.md         (teammate OOO dates as PII)
  2. .github/agents/comms.md                  (Outlook/Teams ingestion)
  3. .github/agents/pm.md                     (named competitive-scan list)
  4. .github/agents/feedback.md               (user-research transcripts)

Removed those plus the orphan skills that only those agents consumed:
competitive-scan, strategy-synthesis, draft-reply, feedback-synthesis,
file-feedback-issue. Removed the paired feedback-inbox.md template.

What remains is a reusable OSS maintainer-assist pattern:

  - 2 agents: dev-maintainer (with two narrow write exceptions), designer
  - 2 skills: audit-pr, ux-audit
  - 3 public-safe inboxes: dev-inbox, designer-inbox, run-log

Reframing changes (no semantic shift, just depersonalized for forkability):

  - "Autonomous agent system (operator-only)" -> "Maintainer assist pattern"
  - "VACATION MODE" -> "observation mode"
  - "Chang" / "the operator" -> "the repository maintainer"
  - CODEOWNERS-VACATIONS lookup -> GitHub native user.status (busy/OOO)
    GraphQL field; owners keep their own status in sync

The dev-maintainer's two narrow vacation-mode writes (audit-only PR comment
+ reviewer request) remain active on merge, unchanged in scope. The
authority-vs-mechanism split from the prior commit still holds: authority
comes from this file on merge; mechanism activates when the operator
updates the schedule prompt post-merge.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs: resolve dev-maintainer 72h escalation + designer observation-mode conflicts (Jake's PR #230 re-review)

Fix two source-of-truth conflicts Jake flagged on 2026-06-08:

1. 72h escalation was effectively a third write exception (polite ping comment) on top of the two narrow writes. Collapsed into the existing narrow write #2: at 72h, request review from a second CODEOWNER on the same path. GitHub's review-request mechanism notifies the new reviewer directly; no separate ping comment needed. Aligned: AGENTS.md (escalation table) + dev-maintainer.md (escalation table + workflow bullet).

2. Designer observation mode was internally inconsistent. AGENTS.md + designer.md said the designer observes and logs to designer-inbox; docs/agents/README.md said the inbox stays empty until activation. Single model now: designer has no schedule by default, so no observation runs. When the maintainer adds a schedule, the designer logs to designer-inbox. External writes (issue files, docs PRs) require separate explicit activation. Aligned: AGENTS.md (Default state + Public-safe inboxes + Designer stays observation-only), designer.md (trigger conditions), docs/agents/README.md (inbox bullet + trailing note).

Non-blocking #3: viewer/ does exist on this branch and on main (verified with git ls-tree). No change needed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jakepresent added a commit that referenced this pull request Jun 13, 2026
Three decisions for the agent-config snapshot path:
- #1 copy blindly: remove node_modules/venv from the exclude floor so a
  runtime's own dependencies are preserved (a broken clone is worse than a
  big one). Floor now drops only secrets + pure churn (sessions/logs/.git).
- #2 absolute-path excludes: agents emit real paths; normalize absolute
  excludes that fall under a root into root-relative globs so they fire.
- #3 external_dependencies: new schema section, consumed by the snapshot as
  copy roots and recorded with kind=external_dependency.

TDD: 4 new tests, 80 local pass. Verified end-to-end through the CLI against
real Hermes paths.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant