Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
179bca6
feat: add managed-validation mode (made validate --managed)
douglasjarquin Aug 19, 2026
ebe15a6
fix(managed): resolve all 7 merge blockers for v1 protocol
douglasjarquin Aug 19, 2026
ca213f9
fix(tests): resolve safe.bareRepository test failures
douglasjarquin Aug 19, 2026
f78f3e2
fix: Add git config to orchestrator package for bare repo support
douglasjarquin Aug 19, 2026
3019acb
fix: Add git config to push and cmd/made packages for bare repo support
douglasjarquin Aug 19, 2026
142803c
fix: Add git config to validateBareGateRepo and related git calls in …
douglasjarquin Aug 19, 2026
5e260d4
fix: Add invocation_id to every event envelope (blocker 3)
douglasjarquin Aug 19, 2026
576079f
fix: Assert exact input_sha and clean workspace before/after stages (…
douglasjarquin Aug 19, 2026
445d93e
fix: Regenerate golden fixtures with invocation_id and correct policy…
douglasjarquin Aug 19, 2026
35c5f45
fix: Add duplicate fingerprint detection in review and document stage…
douglasjarquin Aug 19, 2026
065d59a
fix: gofmt
douglasjarquin Aug 19, 2026
c1ddfc8
fix: Apply redaction to finding descriptions and messages (blocker 5 …
douglasjarquin Aug 19, 2026
abbb334
docs: Add subprocess isolation requirements and update evidence layou…
douglasjarquin Aug 19, 2026
c54cea3
fix: Preserve inherited environment when adding git config overrides …
douglasjarquin Aug 19, 2026
77ef681
fix: Require stable structural identity for managed findings (blocker 2)
douglasjarquin Aug 19, 2026
89d267e
fix: Include complete safeRunID in evidence reference paths (blocker 3)
douglasjarquin Aug 19, 2026
2e3fa63
fix: Remove unused fingerprint helper functions and fix whitespace
douglasjarquin Aug 19, 2026
0cbab2a
docs: Update managed validation protocol to match implementation (blo…
douglasjarquin Aug 19, 2026
6cd0442
test: Add comprehensive fixture validation test (blocker 4 requirement)
douglasjarquin Aug 19, 2026
a16f458
fix: Clean up fixture test lint issues
douglasjarquin Aug 19, 2026
e8328f2
chore: Remove accidentally committed made binary and add to .gitignore
douglasjarquin Aug 19, 2026
4480674
fix: Enforce strict path validation for managed findings (blocker 1)
douglasjarquin Aug 19, 2026
f2ac6a9
fix: Canonicalize evidence root and stricter path validation (blocker 2)
douglasjarquin Aug 19, 2026
678ac21
fix: Remove redundant manifest.json, keep only terminal.json (blocker 4)
douglasjarquin Aug 19, 2026
140ef36
feat: Add managed-specific review contract with strict finding identi…
douglasjarquin Aug 19, 2026
caca962
fix: Correct gofmt formatting issues
douglasjarquin Aug 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

/made
2 changes: 2 additions & 0 deletions cmd/made/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ func validateBareGateRepo(path string) error {
res, err := exec.Run(ctx, exec.Command{
Name: "git",
Args: []string{"-C", path, "rev-parse", "--is-bare-repository"},
Env: gitEnv(),
})
if err != nil {
return fmt.Errorf("check bare repository at %s: %w", path, err)
Expand Down Expand Up @@ -559,6 +560,7 @@ func validateGateSubmission(ctx context.Context, spoolPath, gatePath, ref, newSH
res, err := exec.Run(ctx, exec.Command{
Name: "git",
Args: []string{"-C", absGate, "rev-parse", "--verify", ref + "^{commit}"},
Env: gitEnv(),
})
if err != nil {
return fmt.Errorf("inspect pushed head: %w", err)
Expand Down
16 changes: 13 additions & 3 deletions cmd/made/gate.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ const gateCommandTimeout = 30 * time.Second

const gitZeroSHAValue = "0000000000000000000000000000000000000000"

func gitEnv() []string {
return append(os.Environ(),
"GIT_CONFIG_COUNT=2",
"GIT_CONFIG_KEY_0=commit.gpgsign",
"GIT_CONFIG_VALUE_0=false",
"GIT_CONFIG_KEY_1=safe.bareRepository",
"GIT_CONFIG_VALUE_1=all",
)
}

func runGateCommand(args []string, stdout, stderr *os.File) int {
if len(args) < 1 {
_, _ = fmt.Fprintln(stderr, "usage: made gate init <target-repo-path> <real-remote-url>")
Expand Down Expand Up @@ -251,7 +261,7 @@ func gateInit(ctx context.Context, madeHomeDir, madeBinaryPath, targetRepoPath,
}

func ensureRemote(ctx context.Context, repoDir, name, url string) error {
res, err := exec.Run(ctx, exec.Command{Name: "git", Args: []string{"remote", "get-url", name}, Dir: repoDir})
res, err := exec.Run(ctx, exec.Command{Name: "git", Args: []string{"remote", "get-url", name}, Dir: repoDir, Env: gitEnv()})
if err != nil {
return fmt.Errorf("git remote get-url %s: %w", name, err)
}
Expand All @@ -262,7 +272,7 @@ func ensureRemote(ctx context.Context, repoDir, name, url string) error {
}

func resolveDefaultBranch(ctx context.Context, barePath string) (string, error) {
res, err := exec.Run(ctx, exec.Command{Name: "git", Args: []string{"remote", "show", "origin"}, Dir: barePath})
res, err := exec.Run(ctx, exec.Command{Name: "git", Args: []string{"remote", "show", "origin"}, Dir: barePath, Env: gitEnv()})
if err != nil {
return "", fmt.Errorf("git remote show origin: %w", err)
}
Expand All @@ -285,7 +295,7 @@ func resolveDefaultBranch(ctx context.Context, barePath string) (string, error)
}

func runGit(ctx context.Context, dir string, args ...string) error {
res, err := exec.Run(ctx, exec.Command{Name: "git", Args: args, Dir: dir})
res, err := exec.Run(ctx, exec.Command{Name: "git", Args: args, Dir: dir, Env: gitEnv()})
if err != nil {
return fmt.Errorf("git %s: %w", strings.Join(args, " "), err)
}
Expand Down
14 changes: 14 additions & 0 deletions cmd/made/gate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,13 @@ func testGit(t *testing.T, dir string, args ...string) {
t.Helper()
cmd := exec.Command("git", args...)
cmd.Dir = dir
cmd.Env = append(os.Environ(),
"GIT_CONFIG_COUNT=2",
"GIT_CONFIG_KEY_0=commit.gpgsign",
"GIT_CONFIG_VALUE_0=false",
"GIT_CONFIG_KEY_1=safe.bareRepository",
"GIT_CONFIG_VALUE_1=all",
)
if out, err := cmd.CombinedOutput(); err != nil {
t.Fatalf("git %s (dir=%s): %v: %s", strings.Join(args, " "), dir, err, out)
}
Expand All @@ -157,6 +164,13 @@ func testGitOutput(t *testing.T, dir string, args ...string) string {
t.Helper()
cmd := exec.Command("git", args...)
cmd.Dir = dir
cmd.Env = append(os.Environ(),
"GIT_CONFIG_COUNT=2",
"GIT_CONFIG_KEY_0=commit.gpgsign",
"GIT_CONFIG_VALUE_0=false",
"GIT_CONFIG_KEY_1=safe.bareRepository",
"GIT_CONFIG_VALUE_1=all",
)
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("git %s (dir=%s): %v: %s", strings.Join(args, " "), dir, err, out)
Expand Down
2 changes: 2 additions & 0 deletions cmd/made/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ func run(args []string, stdout, stderr *os.File) int {
}

switch args[0] {
case "validate":
return runValidateCommand(args[1:], stdout, stderr)
case "capabilities":
return runCapabilitiesCommand(args[1:], stdout, stderr)
case "run":
Expand Down
2 changes: 1 addition & 1 deletion cmd/made/runcommands.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func runCapabilitiesCommand(args []string, stdout, stderr *os.File) int {
}
return writeJSON(stdout, capabilitiesReport{
SchemaVersion: 1, ProtocolVersion: api.Version,
Commands: []string{"run.submit", "run.status", "run.list", "run.cancel", "review.decide", "doctor"},
Commands: []string{"run.submit", "run.status", "run.list", "run.cancel", "review.decide", "doctor", "validate.managed.v1"},
Agents: supportedAgentNames(),
}, stderr, "made capabilities")
}
Expand Down
94 changes: 94 additions & 0 deletions cmd/made/validate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package main

import (
"context"
"flag"
"fmt"
"os"
"os/signal"
"syscall"

"github.com/douglasjarquin/made/internal/managed"
)

// runValidateCommand is the entry point for `made validate --managed --json-events ...`.
func runValidateCommand(args []string, stdout, stderr *os.File) int {
fs := flag.NewFlagSet("made validate", flag.ContinueOnError)
fs.SetOutput(stderr)

managedMode := fs.Bool("managed", false, "run in managed-validation mode")
jsonEvents := fs.Bool("json-events", false, "emit JSON-Lines events to stdout")

runID := fs.String("run-id", "", "opaque run identifier echoed in every event")
missionID := fs.String("mission-id", "", "opaque mission identifier echoed in every event")
workspace := fs.String("workspace", "", "absolute path to Git working tree")
baseSHA := fs.String("base-sha", "", "full 40-hex base commit SHA")
inputSHA := fs.String("input-sha", "", "full 40-hex input commit SHA (must equal workspace HEAD)")
trustedConfig := fs.String("trusted-config", "", "absolute path to trusted .made.yml")
policyHash := fs.String("policy-hash", "", "sha256:<64-hex> of trusted-config bytes")
evidenceDir := fs.String("evidence-dir", "", "absolute path outside workspace for evidence output")
decisions := fs.String("decisions", "", "optional absolute path to Decisions JSON file")

if err := fs.Parse(args); err != nil {
return 2
}

if !*managedMode {
_, _ = fmt.Fprintln(stderr, "made validate: --managed is required")
return 2
}
if !*jsonEvents {
_, _ = fmt.Fprintln(stderr, "made validate: --json-events is required")
return 2
}

// Validate required flags.
missing := []string{}
if *runID == "" {
missing = append(missing, "--run-id")
}
if *missionID == "" {
missing = append(missing, "--mission-id")
}
if *workspace == "" {
missing = append(missing, "--workspace")
}
if *baseSHA == "" {
missing = append(missing, "--base-sha")
}
if *inputSHA == "" {
missing = append(missing, "--input-sha")
}
if *trustedConfig == "" {
missing = append(missing, "--trusted-config")
}
if *policyHash == "" {
missing = append(missing, "--policy-hash")
}
if *evidenceDir == "" {
missing = append(missing, "--evidence-dir")
}
if len(missing) > 0 {
for _, flag := range missing {
_, _ = fmt.Fprintf(stderr, "made validate: missing required flag %s\n", flag)
}
return 2
}

opts := &managed.Options{
RunID: *runID,
MissionID: *missionID,
Workspace: *workspace,
BaseSHA: *baseSHA,
InputSHA: *inputSHA,
TrustedConfig: *trustedConfig,
PolicyHash: *policyHash,
EvidenceDir: *evidenceDir,
DecisionsPath: *decisions,
}

ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer cancel()

return managed.Run(ctx, opts, stdout, stderr)
}
Loading
Loading